cin is eating my output

R

rossum

I have been looking at exceptions as I need to get better at using
them.

I came across an interesting effect, demonstrated below. When I
ctrl-Z the input to throw an ios_base::failure, the first line of
output from cout is lost, even if I clear() and flush(). The only way
I have found to get the first line to appear is to put a newline at
the start. It seems to be ignoring everything up to and including the
first newline.

Investigating further I noticed that a triggering an ios_base::failure
by entering a letter did not have the same effect, nor did a spurious
exception. This led me to a possible diagnosis:

1 cin is waiting for input terminated by a newline.
2 I press ctrl-Z triggering an ios_base::failure.
3 Despite the exception cin is still waiting for its input.
4 I pass some text to cout for output.
5 cout puts the text into the console I/O buffer.
6 cin thinks that the text is input.
7 cin takes text from the buffer until the first newline.
8 Having found a newline cin is satisfied and goes away.
9 Screen output can now operate normally.

I assume that the ability of cin to grab text from cout is because
they share the console I/O buffer. The other triggers did not have a
problem because cin got some input terminated by a newline before the
error was thrown and so was no longer waiting for input.

One thing I have not been able to explain is when I use cerr for
output the same effect happens despite cerr being unbuffered. Maybe
the shared buffer is at a lower level in the system.

I am using Win ME and Dev-C++ 4.9.8.0 with the compiler that comes
with it by default. I do not know if this effect is reproducible on
other systems.

Questions:

1 Is my diagnosis roughly correct?
2 Am I doing something stupid?
3 Is there a standard way to tell cin not to eat the output?

Currently I just add an extra '\n' to the front of the first cout, but
this does mean that the output is different depending on how the file
error was triggered and I would rather avoid that if possible.


rossum



#include <iostream>
#include <stdexcept>
#include <cstdlib>


int main() {
using std::cout;
using std::cin;

const int upper_bound = 10;
const int lower_bound = 2;

cout << "Enter an odd number between " << lower_bound << " and "
<< upper_bound << ": ";
int number = 0;

try {
// Use ctrl-Z to trigger the effect.
// Enter a letter to avoid the effect
if (!(cin >> number))
{ throw std::ios_base::failure("Error reading input stream.");
}
// Use 99 to throw a spurious file error - avoids the effect.
if (number == 99)
{ throw std::ios_base::failure("99 entered."); }
if (number % 2 == 0)
{ throw std::invalid_argument("Number is not odd."); }
if (number > upper_bound)
{ throw std::eek:ut_of_range("Number is too large."); }
if (number < lower_bound)
{ throw std::eek:ut_of_range("Number is too small."); }
} // end try

// File error needs special handling
catch (std::ios_base::failure& ferr) {
// cout.clear(); // No effect
// cout.flush(); // No effect
// cin.clear(); // No effect
cout << "This line does not appear on screen.\n" // \n at end
// cout << "\nThis line does appear on screen." // \n at start
// cout << "This doesn't appear.\nThis does." // \n in middle
// std::cerr << "Output through cerr\n" // Using cerr
<< '\n' << number << ": " << ferr.what() << '\n';
} // end catch

// Other errors do not need special handling
catch (std::exception& err) {
cout << number << ": " << err.what() << '\n';
} // end catch

return EXIT_SUCCESS;
} // end main()
 
U

Unforgiven

rossum said:
I have been looking at exceptions as I need to get better at using
them.

I came across an interesting effect, demonstrated below. When I
ctrl-Z the input to throw an ios_base::failure, the first line of
output from cout is lost, even if I clear() and flush(). The only way
I have found to get the first line to appear is to put a newline at
the start. It seems to be ignoring everything up to and including the
first newline.

I just tried reproducing your problem using Visual Studio 2005 beta 1 under
Windows XP SP2 and it does not. The line appears on screen as expected.
Because the MS-DOS prompt from Windows Me is hardly comparable to cmd.exe in
Windows NT derivatives, I also tried running your code under Windows 98,
where the problem did reproduce. One striking difference is that under
Win98, pressing CTRL-Z immediately stops the input, while under Windows XP,
pressing CTRL-Z just prints "^Z" on screen, and I still have to press enter
for the application to continue. It seems then to be something fundamentally
strange about the way Win9x/Me handle CTRL-Z.

Since that makes this a platform issue, and not a C++ issue, your probably
better off asking in a newsgroup where Windows is on-topic.
 
R

rossum

I just tried reproducing your problem using Visual Studio 2005 beta 1 under
Windows XP SP2 and it does not. The line appears on screen as expected.
Because the MS-DOS prompt from Windows Me is hardly comparable to cmd.exe in
Windows NT derivatives, I also tried running your code under Windows 98,
where the problem did reproduce. One striking difference is that under
Win98, pressing CTRL-Z immediately stops the input, while under Windows XP,
pressing CTRL-Z just prints "^Z" on screen, and I still have to press enter
for the application to continue. It seems then to be something fundamentally
strange about the way Win9x/Me handle CTRL-Z.

Since that makes this a platform issue, and not a C++ issue, your probably
better off asking in a newsgroup where Windows is on-topic.

Thanks for the info.

rossum
 
J

Joe C

rossum said:
I have been looking at exceptions as I need to get better at using
them.

I came across an interesting effect, demonstrated below. When I
ctrl-Z the input to throw an ios_base::failure, the first line of
output from cout is lost, even if I clear() and flush().

Is this a problem that can be fixed by calling cin.sync(); before using cin
to get input?
 
R

rossum

Is this a problem that can be fixed by calling cin.sync(); before using cin
to get input?
No joy I'm afraid, but thanks for the suggestion anyway. I suspect
that the solution will be an upgrade. (Looks at piggy bank and
wonders how much is in it.)

rossum
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top