Infinite loop on EOF in C++
c++, cin, eof, std
Solution
You should always check whether any of a stream's failure flags are set after calling formatted extraction operation, in your example you are checking `response` without checking whether `response` was correctly extracted.
Also, you are using `std::endl` in your prompt output where it doesn't make sense. `std::endl` prints `\n` and then flushes the buffer, but you then immediately print more characters so the flush is redundant. As `cin` and `cout` are (usually) tied, calling an input function for `std::cin` will cause `std::cout` to be flushed in any case so you may as well put a `\n` into your prompt string and save on the verbose extra `<<` operators.
Why not make a prompting function that prints the prompt, retrieves the input an returns a reference to the stream so that you can test it for success using the usual stream to boolean type conversion.
This way you can get rid of the while true and explicit break.
std::istream& prompt_for_input( std::istream& in, std::ostream& out, char& response )
{
out << "enter a character at the prompt.\n> ";
in >> response;
return in;
}
int main()
{
char response;
while ( prompt_for_input( std::cin, std::cout, response ) && response != 'q' )
{
wait();
}
}
Problem
This code works as desired for the most part, which is to prompt the user for a single character, perform the associated action, prompt the user to press return, and repeat. However, when I enter ^D (EOF) at the prompt, an infinite loop occurs. I am clearing the error state via std::cin.clear() and calling std::cin.ignore(...) to clear the buffer. What could be causing the infinite loop? ``` #include <iostream> #include <limits> void wait() { std::cout << std::endl << "press enter to continue."; std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cin.clear(); std::cin.get(); } int main() { char response; while (true) { std::cout << "enter a character at the prompt." << std::endl << "> "; std::cin >> response; switch (response) { case 'q': exit(0); break; } wait(); } } ``` I am running this in the Mac OS X terminal, if it matters. UPDATE: What I am really asking here is, when the user enters EOF (^D) at the prompt, how do I (a) detect it and (b) reset the stream so that the user can continue to enter data. The following example is different from the code above, but illustrates the same principle of clearing the stream after a ^D has been detected and continuing to read from that stream. ``` > a you entered: a > b you entered: b > ^D you entered EOF > c you entered: c ... ```