【问题标题】:Injecting string to 'cin'将字符串注入'cin'
【发布时间】:2011-04-17 08:55:36
【问题描述】:

我有一个从 std::cin 读取用户输入的函数,我想编写一个单元测试,将一些字符串插入到 std::cin 中,以便以后从 std::cin 提取将读取该字符串而不是暂停用于键盘输入。

理想情况下,我会更改函数签名,以便可以将自定义 istream 作为参数传递,但我不能在这里这样做,因为我有一个无法更改的固定接口。

cin.putback() 是我想要的几乎,但是它一次只插入一个字符,并且它以相反的顺序插入它们(但我在某处读到放回字符最初并不存在可能是危险的,尽管该网站没有详细说明原因)。我尝试了几种方法将字符串注入 cin 的内部缓冲区 cin.rdbuf(),但也没有一种方法可以工作。我也考虑过使用外部测试脚本或创建子进程,但是我想首先考虑用纯 C++ 进行测试。

那么,有什么方法可以将字符串放入 cin 中吗?或者你知道注入我的“假键盘输入”的更好方法吗?

【问题讨论】:

    标签: c++ iostream


    【解决方案1】:

    您可以让您的程序接受一般的std::istream&,而不是乱搞cin。正常运行时,直接传cin即可。在单元测试期间,将您自己创建的 I/O 流传递给它。

    【讨论】:

    • 这个解决方案真的很棒。如果你想传递一个文件作为测试输入,你可以通过ifstream 传递一个打开的文件,或者如果你只想传递一个字符串作为测试输入,你可以简单地传递一个istringstream
    【解决方案2】:

    如果你真的非常想使用 std::cin,试试这个:

    int main() {
      using namespace std;
      streambuf *backup;
      istringstream oss("testdata");
      backup = cin.rdbuf();
      cin.rdbuf(oss.rdbuf());
      string str;
      cin >> str;
      cout << "read " << str;    
    }
    

    从备份完成后,您可以恢复 std::cin 的 streambuf。 我不保证这个的可移植性;P

    【讨论】:

    • +1。或stringbuf sb("testdata"); streambuf *backup = cin.rdbuf(&amp;sb);。它是合规的,并且具有合理的可移植性,但不是很好的做法。哦,是的,一旦输入用完,他可能不得不做cin.clear() 来逃避EOF 条件:vP。
    • +1 正是我所要求的(我个人仍然想知道,即使对于白盒测试代码,这样做是否是个好主意)。
    【解决方案3】:

    cin.putback() 保证最多可以使用一个字符,因此您不能 putback 使用整个字符串。使用包装 cin 并允许任意 putback() 序列长度的流。我认为Boost.Iostream 有类似的东西,如果没有,那么实现这样的包装器可能会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-15
      • 2016-06-28
      • 2013-01-11
      • 2011-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多