std :: cin可以在运行时从接受文件输入切换到键盘输入吗?

时间:2013-03-25 22:22:19

标签: c++ cin io-redirection

假设我有一个程序接受来自键盘的输入,或者接受来自文件的重定向输入,以便:

#include <iostream>

using namespace std;

int main() {
  string str;
  while (getline(cin, str)) {
    if(str.compare("exit") == 0)
      return 0;
  }
  return 0;
}

在这个实现中,我希望使用键盘输入的程序实例在输入“exit”时终止,并且使用文件输入的程序实例将在EOF时终止。

我想实现这样的功能:如果正在运行的程序实例使用文件输入,它将允许在达到EOF时输入键盘,而不是终止。我做了一些研究表明,getline作为while循环的条件是不可能的,因为一旦文件输入结束它将返回false,我不知道告诉{ {1}}我当时想要接受键盘输入。

那么,cin是否可以在文件运行时从接受文件输入切换到接受键盘输入?如果不是,你能解释一下原因吗?

2 个答案:

答案 0 :(得分:2)

当然可以。 std::cin.rdbuf()函数可以将另一个I / O缓冲区重新分配给cin。但是你必须首先获得缓冲区。

当您使用shell将文件重定向到stdin时,该文件将替换键盘。 shell负责将键盘连接到程序,所以现在你可以自己动手了。 C ++没有定义键盘接口。除非您想使用特定于平台的(可能不值得),否则程序的使用惯例需要稍微改变。

最标准的解决方案是将输入文件添加为命令行选项。这可以很容易地打开为std::filebuf缓冲区对象。将其传递给std::cin.rdbuf(),并保存返回值。现在std::cin从文件中读取。完成后,将保存的值传递给rdbuf,将其恢复为仍连接到键盘的原始stdin文件描述符。

答案 1 :(得分:1)

问题不在于std::cin。使用std::cin.rdbuf(newBuf)可以切换输入源。但是,您的新输入源是什么? ISO C ++不了解键盘。它确实知道标准输入,但这已经设置为文件内容。

您可以将操作系统级键盘界面包装在std::streambuf界面中,但这当然不可移植。