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

C++ How can I redirect STDIN to a function

我花了一些时间研究将 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

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

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

这在大多数情况下是不可能的。部分原因是即使您替换标准输入和标准输出也不够。程序的某些部分可能会尝试以更直接的方式操纵 stdin 和 stdout。

在 Unix 系统上,我会用线程和管道或套接字对来解决这个问题。然后我会使用 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 (for input) and overflow(用于输出)函数过载并且具有完全无缓冲的 streambuf。