This example reads lines with an integer, an operator, and another integer. For example,
25 * 3 4 / 2
It's simple to read each of these three elements, but what happens if something is wrong with the input. For example, errors in the input like
25 * 3 + 1 or 25 *
will cause the whole program to fail. The solution is to read each line into a string, then read from the string. This will isolate the errors to one line, which is something that isn't possible with normal stream I/O, which will simply ignore whitespace, including line breaks. The example below shows how to do this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// sstream-line-input.cpp - Example of input string stream. // This accepts only lines with an int, a char, and an int. // Fred Swartz 11 Aug 2003 #include <iostream> #include <sstream> #include <string> using namespace std; //================================================================ main int main() { string s; // Where to store each line. int a, b; // Somewhere to put the ints. char op; // Where to save the char (an operator) istringstream instream; // Declare an input string stream while (getline(cin, s)) { // Reads line into s instream.clear(); // Reset from possible previous errors. instream.str(s); // Use s as source of input. if (instream >> a >> op >> b) { instream >> ws; // Skip white space, if any. if (instream.eof()) { // true if we're at end of string. cout << "OK." << endl; } else { cout << "BAD. Too much on the line." << endl; } } else { cout << "BAD: Didn't find the three items." << endl; } } return 0; } |
Note that ws
is an input manipulator that skips whitespace.
The flow could be simplified somewhat by making the if
more complicated.
Here is the central part rewritten, adding some calculator code.
if ((instream >> a >> op >> b >> ws) && instream.eof()) { switch (op) { case '+': result = a + b; break; case '-': result = a - b; break; case '*': result = a * b; break; case '/': result = a / b; break; default : cout << "Bad operator '" << op << endl; continue; // next loop iteration } cout << result << endl << endl; } else { cout << "BAD INPUT." << endl; }