简体   繁体   English

运行.exe并重定向stdin并退出

[英]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::cinstd::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::cinstd::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::cinstd::cout仍然分别重定向到instroutstr

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. 此函数对于将预定义流(如stdinstdoutstderr)重定向到特定文件特别有用。

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::cinstd::coutrdbuf ,而子进程有另一个std::cinstd::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. 这就是为什么在stdinstdout上使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM