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

时间:2017-04-19 15:57:50

标签: c++ c++11 redirect

在我生命的大部分时间里,我一直在使用cstdio。现在我试图转移到iostream

假设我有一个名为" foo.cpp"的单独程序。看起来像这样:

int main(){ // foo.cpp
    int x;
    std::cin >> x;
    std::cout << x + 5 << "\n";
}

在另一个名为&#34; bar.cpp&#34;的程序中,我调用了foo可执行文件。在过去,如果我想将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"
}

现在我尝试将std::cinstd::cout重定向到字符串流。像这样:

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"
}

但我所学到的是std::cinstd::cout在执行&#34; foo.exe&#34;时未被重定向。该程序现在预计用户输入并将打印到std::cout。执行&#34; foo.exe&#34;已完成,std::cinstd::cout在&#34; bar.cpp&#34;仍然分别被重定向到instroutstr

我的问题是,有没有办法按照我的意图使用iostream,或者我坚持使用freopen

2 个答案:

答案 0 :(得分:1)

Haven在一段时间内没有看到freopen电话。这带回了一些旧的记忆。

无论如何,我认为你应该坚持使用freopen。该函数的documentation页面字面上表明这是主要用例之一:

  

此功能对于将 stdin stdout stderr 等预定义流重定向到特定文件特别有用。

我认为您不能仅使用iostream进行重定向,因为iostream库没有freopen函数的等价物。

有趣的是,为什么你试过的这个解决方案不起作用:

std::cin.rdbuf(instr.rdbuf());
std::cout.rdbuf(outstr.rdbuf());

也许使用这两行只会影响当前进程中std::cinstd::cout rdbuf ,并且子进程有另一个std::cin和{{}}的实例{1}}。

在调用std::cout时,有关文件的信息似乎从父进程复制到子进程。这就是为什么在 stdin stdout 的主进程中对system进行的更改在子进程中也是可见的。

无论如何,you should not use system从主C ++程序运行子程序。由于你可能在Windows上(从freopen猜测),我会从微软分析这个example。它解释了如何创建子流程并使用管道重定向子程序的输入和输出。

答案 1 :(得分:0)

在使用freopen的示例代码中,您是重定向到物理文件还是从物理文件重定向,对吗?在使用std :: istringstream和std :: ostringstream的示例代码中,您尝试重定向到内存或从内存重定向,对吗?物理文件与内存不同。内存没有文件描述符。在Linux中,您可以像windows - C - create file in memory - Stack Overflow中一样使用fmemopen,但这对C ++标准类(如std :: istringstream和std :: ostringstream)没有帮助,也不能将stdin和stdout重定向到fmemopen或从fmemopen重定向有一点是因为fmemopen并非在所有操作系统中都可用。 C ++标准类不支持这种类型的东西;见c++ - Getting a FILE* from a std::fstream - Stack Overflow。 std :: istream和std :: ostream可能在C ++ interace级别看起来像std :: istringstream和std :: ostringstream,但在内部它们不兼容。