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

C++ How can I redirect STDIN to a function

提问人:Ricardo Antunes 提问时间:11/3/2017 最后编辑:Ricardo Antunes 更新时间:11/3/2017 访问量:888

问:

我花了一些时间研究一种将 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
C++ 跨平台 std iostream stdio

评论

2赞 user0042 11/3/2017
“重定向”是什么意思??你不能只使用和在你的功能中吗?STDOUTSTDIN
0赞 Ricardo Antunes 11/3/2017
对不起,我已经澄清了我的问题。
0赞 Ricardo Antunes 11/3/2017
我真的不明白你说的“只在你的函数中使用 STDOUT 和 STDIN”是什么意思。你能澄清一下吗?
1赞 Omnifarious 11/3/2017
我不相信有办法以跨平台的方式做到这一点。在 Unix 盒子上,我将创建一个并用于将 fd 0 和 1 设置为一端。然后,我会在单独的线程上运行控制台,并让它从另一端读取和写入。socketpairdup2
0赞 Ricardo Antunes 11/3/2017
我目前正在使用 Windows,所以如果没有跨平台的方法可以做到这一点,我现在更愿意使用 Windows。

答:

1赞 Omnifarious 11/3/2017 #1

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

从本质上讲,您要做的是将 替换为 和 ,而不是实际执行输入和输出,而是调用控制台输入和输出例程。stdinstdout

大多数情况下,这并不完全可能。部分原因是,即使您替换了 stdin 和 stdout,也是不够的。程序的某些部分可能会尝试以更直接的方式操纵 stdin 和 stdout。

在 Unix 系统上,我会使用线程和管道或套接字对来解决这个问题。然后,我将使用系统调用来替换文件描述符 0 和 1。这将确保任何程序都无法绕过您的控制台,除非它非常努力地尝试(基本上它必须故意打开并输出到控制台)。dup2/dev/tty

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

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

如果你只是想替换,那可能是可行的,用你自己的对象替换他们的对象。我不太确定如何使它工作,但我认为您应该查看 and 对象的 rdbuf 成员函数coutcinstreambufcincout

实现自己的并不难。我只需要自己做。不幸的是,即使代码没有特别具体地针对我在这里工作的任何细节,代码仍然是专有的,所以我无法粘贴它。但是,在Josuttis关于C++标准库的书中的各种代码示例中有许多这样的例子。streambuf

对于您的特定情况,您可能会使用自己的 streambuf,它只是使下溢(用于输入)和溢出(用于输出)函数过载,并且具有完全无缓冲的 streambuf。

评论

0赞 Ricardo Antunes 11/3/2017
谢谢你的回答。根据你说的,我看到我将无法使用 STDIN 和 STDOUT 实现我想要的东西,那么重定向 std::cout 和 std::cin 呢?
1赞 Omnifarious 11/3/2017
@RicardoAntunes:更新了如何做和。coutcin
1赞 Omnifarious 11/3/2017
@RicardoAntunes:还有一点细节。:-)