The scenario is: input integers and characters alternatively and read them into variables of the right type. I took the straightforward approach: read anyways as if they were all integers; when failed, reset cin flags and read as characters.
int a; char c; while (true) { cin >> a; if (cin.fail()) { if (cin.eof()) { cout << "eof" << endl; break; } cin.clear(); cin >> c; cout << "fail: " << c << ": " << int(c) << endl; } else { cout << "success: " << a << endl; } } It works just fine except for the very two characters: +, -. For instance, when you input 2 4 + 5 *, the output would be:
success: 2 success: 4 fail: 5: 53 fail: *: 42 eof For *, it works; but for +, it seems that + is lost and 5 is read instead. I did some tests myself (e.g. using cin.get() instead) and found that: after cin >> a failed when encoutering +, + is consumed and the stream position points at the space between + and 5.
What makes + and - special? After some researches, I think the reason is possibly that: when cin expects an integer, the + or - it encounters is accepted as a possible prefix of integers like +5, -3, etc. This leads to the fact that + is consumed, rather than remains in the input stream like other characters.
How do you interpret the problem? How to fix the code to make it function properly?
PS: I know that one alternative solution is to read them all as strings and then do further parsing. I'm just curious whether it's possible to modify it based on the original approach. This way I could be more clear about the machanisms behind cin.
I think this post can be closed now. Thanks for all the comments and answers. The opinions and advice you shared are greatly appreciated, which I learned a lot from.
As I've said, it's not about practical use and I'm not looking for a well-rounded solution in the first place. In practice I will surely take the string-based approaches as suggested by you. It's just a small problem I ran into, after which I decided to take a short digression and play around the issue a little bit.
As for the question I raised, i.e. fixing the code, I've learned some from the answers below and official Docs. Using functions like cin.putback() cin.peek() cin.tellg() cin.seekg() will help tackle the problem.
123abc. Do you consider that to be an integer followed by a string, or, because there is no space, a single string? Your approach will choose the former interpretation, but most users I think would choose the later.cin >> a;reads+ 5it will extract+then will encounter space and report an error, since only digits are expected.+without digits can't be interpreted as a number. After you have clear the error you docin >> c;which will ignore space (which lead to an error) and then character5is extracted. Basically+is not put back into a stream after later failure is encountered.