[英]Run .exe and redirect stdin and out
For most of my life, I've been using cstdio
. 在我生命的大部分时间里,我一直在使用
cstdio
。 Now I'm trying to shift over to iostream
. 现在我正试图转移到
iostream
。
Suppose I have a separate program called "foo.cpp" that looks like this: 假设我有一个名为“foo.cpp”的独立程序,如下所示:
int main(){ // foo.cpp
int x;
std::cin >> x;
std::cout << x + 5 << "\n";
}
In another program called "bar.cpp", I call the foo executable. 在另一个名为“bar.cpp”的程序中,我调用了foo可执行文件。 In the past, if I wanted to redirect stdin and stdout to a file, I would use
freopen
like so: 在过去,如果我想将stdin和stdout重定向到一个文件,我会像这样使用
freopen
:
int main(){ // bar.cpp, redirecting stdin and stdout
freopen("foo.in", "r", stdin); // Suppose "foo.in" contains a single integer "42"
freopen("foo.out", "w", stdout);
system("foo.exe"); // "foo.out" will contain "47"
}
Now I'm trying to redirect std::cin
and std::cout
to stringstreams. 现在我正在尝试将
std::cin
和std::cout
重定向到stringstreams。 Something like this: 像这样的东西:
int main(){ // bar.cpp, redirecting cin and cout
std::istringstream instr("62");
std::ostringstream outstr;
std::cin.rdbuf(instr.rdbuf());
std::cout.rdbuf(outstr.rdbuf());
system("foo.exe"); // outstr should contain "67"
}
But what I've learned is that std::cin
and std::cout
was not redirected when executing "foo.exe". 但我学到的是执行“foo.exe”时没有重定向
std::cin
和std::cout
。 The program now expected user input and will print to std::cout
. 该程序现在预计用户输入并将打印到
std::cout
。 When execution of "foo.exe" was done, std::cin
and std::cout
within "bar.cpp" still remained redirected to instr
and outstr
respectively. 执行“foo.exe”时,“bar.cpp”中的
std::cin
和std::cout
仍然分别重定向到instr
和outstr
。
My question is, is there a way to do it with iostream
like I intended, or am I stuck with using freopen
? 我的问题是,有没有办法像我想的那样使用
iostream
,或者我是否坚持使用freopen
?
Haven't seen a freopen
call in a while. 有段时间没见过
freopen
电话。 This brings back some old memories. 这带回了一些旧的记忆。
Anyway, I think you should stick with freopen
. 无论如何,我认为你应该坚持使用
freopen
。 The documentation page of the function literally states that this is one of the main use cases: 该函数的文档页面字面上表明这是主要用例之一:
This function is especially useful for redirecting predefined streams like stdin , stdout and stderr to specific files.
此函数对于将预定义流(如stdin , stdout和stderr)重定向到特定文件特别有用。
I don't think you can do the redirection with iostream
only, because the iostream
library doesn't have an equivalent for the freopen
function. 我不认为你只能用
iostream
进行重定向,因为iostream
库没有freopen
函数的等价物。
It is interesting though why this solution you tried doesn't work: 有趣的是,为什么你试过的这个解决方案不起作用:
std::cin.rdbuf(instr.rdbuf());
std::cout.rdbuf(outstr.rdbuf());
Maybe with those two lines you just affect the rdbuf of std::cin
and std::cout
from the current process and the subprocess has another instance of std::cin
and std::cout
. 也许使用这两行你只会影响当前进程中
std::cin
和std::cout
的rdbuf ,而子进程有另一个std::cin
和std::cout
实例。
The information about files seems to be copied from the parent process to the subprocess when calling system
. 在调用
system
时,有关文件的信息似乎从父进程复制到子进程。 That is why the changes you do in the main process on stdin and stdout with freopen
are also visible in the subprocess. 这就是为什么在stdin和stdout上使用
freopen
在主进程中所做的更改在子进程中也是可见的。
Regardless, you should not use system to run a subprogram from your main C++ program. 无论如何, 您不应该使用系统从主C ++程序运行子程序。 As you are probably on Windows (guessing from
foo.exe
), I would analyze this example from Microsoft. 由于你可能在Windows上(从
foo.exe
猜测),我会从微软分析这个例子 。 It explains how to create a subprocess and use pipes to redirect the input and output of the subprogram. 它解释了如何创建子流程并使用管道重定向子程序的输入和输出。
In your sample code using freopen, you are redirecting to/from physical files, correct? 在使用freopen的示例代码中,您是重定向到物理文件还是从物理文件重定向,对吗? In your sample code using std::istringstream and std::ostringstream you are trying to redirect to/from memory, correct?
在使用std :: istringstream和std :: ostringstream的示例代码中,您尝试重定向到内存或从内存重定向,对吗? Physical files are not the same as memory.
物理文件与内存不同。 Memory does not have file descriptors.
内存没有文件描述符。 In Linux you can use fmemopen as in windows - C - create file in memory - Stack Overflow but that won't help with C++ standard classes such as std::istringstream and std::ostringstream nor would you be able to redirect stdin and stdout to/from fmemopen, for one thing because fmemopen is not available in all operating systems.
在Linux中你可以像在windows中一样使用fmemopen - C - 在内存中创建文件 - Stack Overflow但是这对c ++标准类如std :: istringstream和std :: ostringstream没有帮助你也不能重定向stdin和stdout往返于fmemopen,因为fmemopen并非在所有操作系统中都可用。 The C++ standard classes don't support this type of thing;
C ++标准类不支持这种类型的东西; see c++ - Getting a FILE* from a std::fstream - Stack Overflow .
请参阅c ++ - 从std :: fstream获取文件* - Stack Overflow 。 std::istream and std::ostream might look like std::istringstream and std::ostringstream at the C++ interace level but internally they are not compatible.
std :: istream和std :: ostream可能在C ++ interace级别看起来像std :: istringstream和std :: ostringstream,但在内部它们不兼容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.