2017-04-19 82 views
5

对于我生命中的大部分时间,我一直在使用cstdio。现在我试图转移到iostream运行.exe并重定向标准输入和输出

假设我有一个名为“Foo.cpp中”一个独立的程序,看起来像这样:

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

在所谓的“bar.cpp”另一个程序,我叫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到stringstreams。事情是这样的:

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执行“foo.exe的”时,没有重定向。该程序现在预计用户输入并将打印到std::cout。当执行“foo.exe”时,“bar.cpp”中的std::cinstd::cout仍分别重定向到instroutstr

我的问题是,有没有像我想要的那样用iostream这样做的方法,还是我坚持使用freopen

+1

操作系统负责处理可执行文件的输出。 C++语言没有重定向输出的功能。 –

+1

用于在程序之间共享数据的常见解决方案:文件,套接字,管道(告诉OS将其他程序的管道输出转换为程序的标准输入),共享内存区域。在网上找。 –

+1

你是否试过只做同样的freopen调用? – stark

回答

1

有一段时间没有看到freopen调用。这带回了一些旧的回忆。我想你应该坚持freopen。该documentation页面中的功能的字面规定,这是主要的用例之一:

该功能对重定向预定义流像标准输入标准输出标准错误到特定的文件特别有用。

我不认为你可以做重定向,只有iostream,因为iostream库没有对freopen功能的等价物。

但为什么这个解决方案,您试过不行有趣的是:

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

也许与两行你只是影响rdbuf的std::cin和从当前进程std::cout和子有另一个std::cinstd::cout的实例。

当调用system时,关于文件的信息似乎从父进程复制到子进程。这就是为什么您在stdin标准输出freopen的主进程中所做的更改也在子流程中可见。

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

0

在使用freopen的示例代码中,您重定向到物理文件/从物理文件重定向?在使用std :: istringstream和std :: ostringstream的示例代码中,您试图重定向到/从内存中更正?物理文件与内存不一样。内存没有文件描述符。在Linux中,您可以使用fmemopen,如windows - C - create file in memory - Stack Overflow,但这对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,但在内部它们不兼容。