如何将数据重定向到单个可执行文件中的stdin?

时间:2020-03-06 14:49:16  来源:igfitidea点击:

我正在使用cxxtest作为C ++类的测试框架,并想找到一种方法来模拟将数据发送到通常希望从标准输入接收数据的类。我有几个不同的文件,希望在不同的测试过程中发送给类,因此无法从命令行重定向到测试套件可执行文件。

基本上,我真正想做的是找到一种方法来重新定义" stdin"句柄或者将其重定向到我在程序内部创建的其他值,然后从这些测试中使用fwrite()以便相应的fread()类内部从程序内部而不是与可执行文件关联的实际标准I / O句柄中提取数据。

这有可能吗?奖励指向与平台无关的解决方案,但至少,在Windows下使用Visual Studio 9时,我需要使用此功能。

解决方案

适当的方法是重写类,使其可测试。他们应该接受应该从中读取测试框架中的数据的句柄,流或者文件作为参数,然后可以在流中进行模拟或者提供包含测试数据的文件的路径。

我们应该能够使用freopen()将stdin指向任意文件。

我认为我们希望类直接使用输入流而不是std :: cin。我们需要将输入流传递到类中,或者通过某种方法在其上进行设置。例如,我们可以使用stringstream来传递测试输入:

std::istringstream iss("1.0 2 3.1415");
some_class.parse_nums(iss, one, two, pi);

rdbuf完全可以满足需求。我们可以打开一个文件进行读取,并将cin的rdbuf替换为文件中的rdbuf。 (有关使用cout的示例,请参见链接)。

在类似Unix的操作系统上,我们可以关闭0文件句柄(stdin)并打开另一个文件。它具有最低的可用句柄,在这种情况下为0。或者使用正好做到这一点的posix调用之一。我不确定,但是在Windows上也可以。

我们可以重定向cin,以便它从文件中读取数据。这是一个例子:

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::ifstream inputFile("Main.cpp");
    std::streambuf *inbuf = std::cin.rdbuf(inputFile.rdbuf());

    string str;
    // print the content of the file without 'space' characters
    while(std::cin >> str)
    {
        std::cout << str;
    }

    // restore the initial buffer
    std::cin.rdbuf(inbuf);
}