# C++ Notes: String stream example

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;
    }