我可以配置"stdin"以从 c++ 字符串中读取吗?
Can I configure `stdin` to read from a c++ string?
我有很多用C编写的第三方函数,它们期望它们的输入从stdin
到scanf()
。我已经用C++编写了其他调用 c 函数的函数。现在,我正在准备测试,我想用C++字符串编写输入测试用例。
所以我的问题是,是否有一种方法可以表达stdin
应该从C++字符串而不是标准输入中读取?如果我做到了这一点,那么我可以编写几个输入是 c++ 字符串的测试用例,并且我的 C++ 函数(调用 c 函数期望从stdin
输入)将被透明调用。
我不确定它的可移植性如何,但至少在 Linux 上使用 gcc-6.3,您可以重新分配stdin
指向不同的流,然后 scanf() 将透明地使用它,就好像它仍在从终端读取一样。如果你想从预先存在的字符串中读取,可以使用类似fmemopen()的东西打开这个新流,它应该在POSIX系统上可用。这允许您从内存块(例如std::string
的内容)创建FILE*
。
作为说明,以下代码将从字符串"String with 3.14159 * 2"
中scanf()
五个值,就好像它们是从终端输入的一样:
#include <cstdio>
#include <iostream>
#include <string>
#include <unistd.h>
int main(int argc, char *argv[])
{ const std::string input("String with 3.14159 * 2");
char s0[16], s1[16], s2[8];
double pi = 3;
int two = -2;
{ FILE *old_stdin = stdin;
FILE* strm = fmemopen((void*)input.c_str(), input.size(), "r");
stdin = strm;
scanf("%s %s %lf %s %d", s0, s1, &pi, s2, &two);
std::cout << "s0="" << s0 << "" s1="" << s1 << """
<< " pi=" << pi << " s2="" << s2 << """
<< " two=" << two << std::endl;
stdin = old_stdin;
fclose(strm);
}
scanf("%12s", s0);
std::cout << "Stdin: "" << s0 << """ << std::endl;
return 0;
}
这将生成以下输出:
s0="String" s1="with" pi=3.14159 s2="*" two=2
在stdin
返回到其正常行为之前,第二个scanf()
等待来自终端的输入。
使用dup2()
(如此处使用)尝试类似的方法很诱人,但似乎通过对从fmemopen()
返回的值调用fileno()
返回的文件描述符无效(在我的系统上为 -1)。
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 无法找到/读取配置文件.conf-FileIOException
- 如何使用Luacneneneba API正确读取字符串和表参数
- C++将文本文件中的数据读取到结构数组中
- 正在将csv文件读取为双精度矢量
- 为什么 sscanf 无法从一个字符串中读取uint64_t和字符?
- 为什么在读取文件大小时文件IO速度会发生变化
- 正在读取二进制文件(is_open)
- 如何在c++中从文本文件中逐行读取整数
- SSH通过/sbin/SSH无法读取RSA密钥文件(从控制台运行)
- 独立读取-修改-写入顺序
- 从文本文件中读取时钟时间和事件时间并进行处理
- 如何从文本文件中读取值和数组
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 一种在C++中读取TXT配置文件的简单方法