Course List http://www.c-jump.com/bcc/
Program should expect a lot of input-related errors:
hardware errors
user typing mistakes
number formatting errors
numeric values out of range
pets walking on the keyboard, etc.
File I/O Error handling (later.)
Condition | Meaning |
---|---|
|
operation succeeded;
!cin.good() is usually abbreviated as !cin (pronounced as "if cin is not good, then...") |
|
operation succeeded;
nothing else is left to input. |
|
nothing wrong with cin;
however, the input formatting has failed, (as when reading "abc" when 123 was expected.) The program should try to recover and continue. |
|
something really bad happened to cin;
cin is no longer usable and should be abandoned. No recovery is possible. |
#include <iostream> using std::stream; int main() { int value = 0; cin >> value; if ( !cin ) { // cin is not good, more checks required: if ( cin.bad() ) { // cin is corrupted return 1; // signal error back to the operating system } if ( cin.eof() ) { // nothing to do: we want all inputs to end like this! return 0; // signal success to the operating system } if ( cin.fail() ) { cin.clear(); // prepare for more input... // do something to recover... } } // use value, everything is ok return 0; }
After
cin.clear();
the stream goes back to
cin.good()
state. Now what?
Great news: the data in the input stream buffer hasn't been lost!
For example,
#include <iostream> using std::cin; using std::cout; int main() { int value = 0; cin >> value; if ( !cin ) { // cin is not good, more checks required: if ( cin.bad() ) { // cin is corrupted return 1; // signal error back to the operating system } if ( cin.eof() ) { // nothing to do: we want all inputs to end like this! return 0; // signal success to the operating system } if ( cin.fail() ) { cin.clear(); // go back to good state... // do something to recover... char ch = 0; while ( cin >> ch ) { cout << "Recovered char(" << int( ch ) << ")\n"; } } } // use value, everything is ok return 0; }
#include <iostream>
using std::cin;
int main()
{
int value = 0;
if ( !( cin >> value ) ) {
// cin is not good, more checks required...
if ( cin.bad() ) {
// stream is corrupted...
}
if ( cin.eof() ) {
// no data is available...
}
if ( cin.fail() ) {
cin.clear(); // go back to good state...
// do something to recover...
}
}
// use value, everything is ok
return 0;
}
#include <iostream>
using std::cin;
using std::cout;
int main()
{
cout << "Please type some numbers separated by spaces or semicolons.\n";
cout << "Type CTRL+Z followed by ENTER on windows (or CTRL+D on unix) to exit.\n";
for (;;) {
int value = 0;
if ( !( cin >> value ) ) {
// cin is not good, more checks required.
// NOTE: the value is likely to contain garbage!
if ( cin.bad() ) {
cout << "cin is corrupted, exiting the program.\n";
return 1; // signal error back to the operating system
}
if ( cin.eof() ) {
cout << "EOF found, exiting the program.\n";
return 0; // signal success to the operating system
}
if ( cin.fail() ) {
cin.clear(); // go back to good state.
// do something to recover...
char ch = 0;
if ( cin >> ch ) {
if ( ch == ';' ) {
// semicolon is data delimiter, and can be ignored:
continue;
}
cout << "Sorry, character [" << ch << "] was unexpected at this time. Exiting...\n";
break;
}
}
}
cout << "You entered: " << value << '\n';
}//for
return 0;
}
What if we need a function that can
check next character;
if necessary, put the character back into the input buffer.
This allows to have functions sensitive to various types of input.
For example, program cin_unget_char.cpp ( download ) illustrates:
stand-alone function named get_value( ) to input a single integer
main( ) function that reports an error to the user. That is, the user dialog is separated from the get_value( ) function.
cin.unget()
call to put the last character back into the input buffer.
cin.clear( ios_base::failbit )
call, which transitions cin object into the state corresponding to cin.fail().
Write a C++ program to
Read user input and skip all digits. Print the result on the screen.
Read user input line-by-line into a string object. Print each line pretending no digits were entered.
Read the content of HTML file. For example,
C:\CIS60> myprog.exe < webpage.html
(a) Print all text without HTML tags.
(b) Print all tag names. Indent nested tags:
html body p img
(c) Same as above, convert the output to UPPERCASE:
HTML BODY P IMG
(d) Same as above, plus count the total number of HTML tags and print the result.
Modify cin_unget_char.cpp sample, so that:
Add functionality to validate that entered numbers fall within the specified range of values.
Allow get_value( ) function to treat numbers enclosed in parenthesis as negative values.
For example,
(123)
should be taken as
-123
and so on.
Modify the program to process doubles instead of ints.
Add a parameter to control the precision of entered doubles.
Treat entered doubles as currency. Print the results in nicely aligned manner and add the totals at the end.
Same as above, but print all negative amounts in parenthesis. That is, -123.456789 should be displayed as
(123.46)