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

C++ How can I redirect STDIN to a function

本文关键字:重定向 函数 STDIN C++      更新时间:2023-10-16

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

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

提前谢谢。

编辑:我用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也不够。程序中可能有一些部分试图以更直接的方式操作stdin和stdout。

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

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

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

如果您只想替换coutcin,那么用您自己的对象替换它们的streambuf对象可能是可行的。我不确定如何实现这一点,但我认为您应该看看cincout对象的rdbuf成员函数。

实现自己的streambuf并不难。我只能自己做。不幸的是,尽管代码中没有任何特定于我在这里工作的细节的内容,但代码仍然是专有的,所以我不能粘贴它。但在Josuttis关于C++标准库的书中的各种代码示例中,有很多这样的例子。

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