问题
Suppose I have a program that accepts input from the keyboard, or alternatively accepts redirected input from a file such that:
#include <iostream>
using namespace std;
int main() {
string str;
while (getline(cin, str)) {
if(str.compare("exit") == 0)
return 0;
}
return 0;
}
In this implementation, I expect that an instance of the program using keyboard input will terminate upon typing "exit", and that an instance of the program using file input will terminate upon EOF.
I would like to implement functionality such that if an instance of the program is running that uses file input, it will allow for keyboard input upon reaching EOF, instead of terminating. I have done some research which suggests that this isn't possible with getline
as the condition for the while loop, because it will return false once the file input ends, and I don't know of a way to tell cin
that I want to accept keyboard input at that time.
So, is it possible for cin
to switch from accepting file input to instead accepting keyboard input while the file is running? If it is not, could you explain why?
回答1:
Sure you can. The std::cin.rdbuf() function can reassign another I/O buffer to cin
. But you have to obtain the buffer first.
When you use the shell to redirect a file to stdin
, the file replaces the keyboard. The shell is otherwise responsible for connecting the keyboard to the program, so now you're left on your own. C++ doesn't define a keyboard interface. Unless you want to use a platform-specific one (probably not worth it) the usage convention of the program needs to change a little.
The most standard solution is to add the input file as a command-line option. This can easily be opened up as a std::filebuf
buffer object. Pass that to std::cin.rdbuf()
, and save the return value. Now std::cin
reads from the file. When finished, pass the saved value to rdbuf
to restore it to the original stdin
file descriptor, which is still connected to the keyboard.
回答2:
The problem isn't with std::cin
. Using std::cin.rdbuf(newBuf)
you can switch input sources. However, what's your new input source? ISO C++ has no idea about keyboards. It does know about standard input, but that's already set to the file contents here.
You can wrap the OS level keyboard interface in a std::streambuf
interface, but that's of course not portable.
来源:https://stackoverflow.com/questions/15625956/can-stdcin-switch-from-accepting-file-input-to-keyboard-input-at-run-time