Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to validate bad input from a file stream?

I want to handle input validation in my such small program.

I have a file containing integer values separated by white spaces. But sometimes there’s invalid values, for example letters or any other non-digit characters. So, I want to ignore those invalid values and push only the valid ints in a vector of integers.

Here is what I’ve tried out so far:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

ifstream in("values");
if(!in)
    throw runtime_error("File \'values\' was not properly opened!");

vector<int> v;
int x = 0;
while( !(in >> x).eof() ){
    if( !in.fail() )
        v.push_back(x);
    else{
        cout << "Invalid input\n";
        in.clear();
        in.ignore(numeric_limits<streamsize>::max(), '\n');
    }
}

for(int val : v)
    cout << val << ", ";

The input file values contain this:

5 7 23 16 81 v 1474 119 21 29 5 88*

The output:

Invalid input
5, 7, 23, 16, 81,

Why v causes reading to stop? And why clearing the stream didn’t put it back in a valid state so that it can read the remaining valid value?

What matters to me a lot is: If I use std::cin input stream in the very same program with the very same input values, I get it correctly and as I expected:

Input:

5
7
23
16
81
v
Invalid input
1474
119  
21
29
5
88*
Invalid input
Ctrl+D (eof)

Output:

5, 7, 23, 16, 81, 1474, 119, 21, 29, 5, 88, 

>Solution :

Your input file has everything on 1 line, so what do you think will happen when v is encountered and then in.ignore() is called to ignore everything up to the next '\n' (line break)? That’s right, it will ignore the rest of the file!

When using cin, your input values are on separate lines, so calling ignore() with '\n' will ignore only the rest of the current line, leaving subsequent lines available for reading.

To solve your issue, try using ' ' (space) instead of '\n' (line break) when calling ignore() on your file stream.

Online Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading