title: skip single minus or plus signs among integer input
body: <p>Recently I needed a simple program to sum all integers occurring on standard input, one integer per line. The input happened to contain some unset lines, containing a single minus ('-') sign, and also some lines with junk characters (to be ignored). </p>
  
  <p>This would be a trivial program, I believed. But as it turned out the single minus signs didn't behave as other bad input. On normal non-integer input the fail flag is set and the bad input remains in the input buffer. But with a single minus (or plus) sign the fail flag is set, but the +/- sign is removed, causing the program to skip the next (valid) integer (causing wrong sum).</p>
  
  <p>I wrote a small test program (below) to analyze the behavior.
  Is the above described behavior with +/- signs a bug or a feature?</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  using namespace std;
  
  int main()
  {
    string s;
    int n;
  
    while (true)
    {
      n = -4711;
      cin &gt;&gt; n;
  
      cerr &lt;&lt; (cin.bad()  ? "ERROR: badbit is set\n" : "");
      cerr &lt;&lt; (cin.fail() ? "ERROR: failbit is set\n" : "");
      cerr &lt;&lt; (cin.eof()  ? "ERROR: eofbit is set\n" : "");
  
      if ( cin.bad() || cin.eof() )
        break;
  
      if ( cin.fail() )
      {
        cin.clear();
        cin &gt;&gt; s;
        cerr &lt;&lt; "ERROR: ignored string '" &lt;&lt; s
             &lt;&lt; "' (integer is '" &lt;&lt; n &lt;&lt; "')" &lt;&lt; endl;
      }
      else
      {
        cout &lt;&lt; "OK: read integer '" &lt;&lt; n &lt;&lt; "'" &lt;&lt; endl;
      }
    }
    return 0;
  }
  </code></pre>
  
  <p>Running the program (with input: "1 asdf 2 - 3 + 4 qwer 5"):</p>
  
  <pre><code>~ $ ./a.out
  1 asdf 2 - 3 + 4 qwer 5 
  OK: read integer '1'
  ERROR: failbit is set
  ERROR: ignored string 'asdf' (integer is '0')
  OK: read integer '2'
  ERROR: failbit is set
  ERROR: ignored string '3' (integer is '0')
  ERROR: failbit is set
  ERROR: ignored string '4' (integer is '0')
  ERROR: failbit is set
  ERROR: ignored string 'qwer' (integer is '0')
  OK: read integer '5'
  </code></pre>
  
  <p>(I already solved my original problem by reading strings instead, and using C++11 stoi with exceptions to identify bad input.)</p>
  
  <p>Edit: If anyone is interested in the solution to my original problem:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  
  using namespace std;
  
  int main()
  {
    int sum = 0;
    string n;
  
    while ( cin &gt;&gt; n )
    {
      try {
        sum += stoi(n);
        cout &lt;&lt; n &lt;&lt; endl;
      }
      catch (exception&amp; e)
      {
        cerr &lt;&lt; e.what() &lt;&lt; " ERROR: '" &lt;&lt; n &lt;&lt; "' is not a number." &lt;&lt; endl;
      }
    }
    cout &lt;&lt; sum &lt;&lt; endl;
  
    return 0;
  }
  </code></pre>