1

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

#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,而且我不知道有什么方法可以告诉cin我要接受键盘当时输入。

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

4

2 回答 2

2

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

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

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

于 2013-03-26T09:14:41.733 回答
1

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

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

于 2013-03-26T08:03:01.977 回答