Search code examples
c++inputstreaminvalid-characters

cin.clear() doesn't reset cin object


I have the following loop. It should read numbers until EndOfFile, or the user input -999

int arr[100];

int index;

for (index = 0; index < 100; index++)
{
 cin >> arr[index];
 if (!cin)
 {
  cin.clear();
  index--;
  continue;
 }
 if (arr[index] == -999)
 {
     break;
 }
}

When the user input an invalid thing, such as some chars, this loop is being repeated for ever without clearing the error state or stopping.


Solution

  • After calling clear, you must also somehow remove the invalid input from the stream. Here is one way:

     cin >> arr[index];
     if (!cin)
     {
      cin.clear();
      std::string ignoreLine; //read the invalid input into it
      std::getline(cin, ignoreLine); //read the line till next space
      index--;
      continue;
     }
    

    It's because when cin fails to read the invalid input, it remains there in the stream. It has to be removed, by some means. I just read and ignore it.

    You can also use ignore as:

    cin.clear();
    cin.ignore(std::numeric_limits<streamsize>::max(),' ');
    

    which is better in my opinion provided inputs are space separated (and if you don't want to inspect the invalid input). The online doc says:

    istream::ignore

    istream& ignore( streamsize n = 1, int delim = EOF );

    Extract and discard characters

    Extracts characters from the input sequence and discards them.

    The extraction ends when n characters have been extracted and discarded or when the character delim is found, whichever comes first. In the latter case, the delim character itself is also extracted.