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:
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,
CodePudding user response:
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:
in.ignore(numeric_limits<streamsize>::max(), ' ');