C ++如何将STDIN重定向到函数

时间:2017-11-02 19:03:48

标签: c++ cross-platform std iostream stdio

我花了一些时间研究将STDOUT和STDIN重定向到函数的方法。

虽然我最终找到并成功将STDOUT重定向到回调,但我也无法将STDIN重定向到回调(除了将STDIN重定向到文件之外,我无法找到任何资源)。

提前致谢。

编辑: 我用windows窗体制作了一个自定义控制台,并且我已将它与管道连接到我的主程序。我已经可以使用它来打印和阅读它了:

Console::PrintLn("Hello World!");
std::string in;
Console::ReadLn(in);

但我的目标是使用例如:

std::string str;
std::cin >> str; // Read string from custom console
std::cout << str << std::endl; // Print string to custom console
std::printf("Hi!"); // It should also work with printf

1 个答案:

答案 0 :(得分:1)

所以,我不相信你可以跨平台的方式做到这一点。

基本上你要做的是用一些代替实际输入和输出的东西替换stdinstdout,调用你的控制台输入和输出例程。

这主要是不可能的。部分原因是即使你替换stdin和stdout也是不够的。可能有部分程序试图以更直接的方式操纵stdin和stdout。

在Unix系统上,我会用线程和管道或socketpairs来解决这个问题。然后我将使用dup2系统调用来替换文件描述符0和1.这将确保没有程序可以绕过你的控制台,除非它非常努力(基本上它必须打开/dev/tty并输出有目的地)。

在Windows上,我不知道我要做些什么来完全解决这个问题。您可以尝试使用freopen来替换stdinstdout。这适用于大多数代码,因为它将使用标准库调用。并且cincout应该实际使用下面的C stdio,以便它们可以与可能在另一个线程上运行的C代码互操作。

我不确定Visual C / C ++版本中的FILE * stdio库是否包含任何可以让IO重定向到回调的内容,所以你可能仍然必须以某种方式使用Windows等效的管道来实现这一点。

如果您只想将coutcin替换为您自己的streambuf对象,那么这可能是可行的。我不确定如何使这项工作,但我认为您应该查看cincout对象的rdbuf member functions

实施自己的streambuf并不难。我必须自己做这件事。不幸的是,即使代码中没有任何特别针对我在这里工作的任何细节的具体内容,代码仍然是专有的,所以我无法粘贴它。但是various code samples from a Josuttis book on the C++ standard library中有很多例子。

对于您的特定情况,您可能会使用自己的streambuf,只是重载了underflow(用于输入)和overflow(用于输出)函数,并且拥有完全无缓冲的streambuf。