+ 1

How to use cin.fail() properly?

I tried to use cin.fail() for making a simple type control, like this: int var; do { cin >> var; } while (cin.fail()); I hoped that the loop would run until an int is entered, but for some reason I get a runtime error (not only on Sololearn). What is the problem?

3rd Oct 2018, 3:40 PM
HonFu
HonFu - avatar
6 Réponses
+ 1
You're closer to the hardware here than in Python so you have more responsibility (like, when the input stream is broken you're expected to repair it with cin.clear() and resynchronize with cin.ignore(skiplen, '\n')). Also...there's a nasty side-effect in your original code that's not apparent at SoloLearn, but try this at home: * Enter 1, everything's fine, code exits. * Enter a, all your CPUs instantly try to peg out at 100% utilization. This occurs because 'a' breaks the input stream cin.fail() sends control back to cin cin automatically fails with no action cin.fail() stays true... ...and this spins out the interactive (foreground) scheduler in an extremely tight loop (i.e. ++lag).
3rd Oct 2018, 7:44 PM
Kirk Schafer
Kirk Schafer - avatar
+ 2
HonFu Hehehe I don't know what to say, comparing Python & C++ probably comes to a never-ending discussion, at times I do envy how things are done much simpler in Python, but I guess these languages has their own strengths & weaknesses :D
3rd Oct 2018, 4:29 PM
Ipang
+ 1
HonFu I just tried this in Playground, I think it may work, just give it a try : ) int var; bool OK {false}; do { cin >> var; OK = !cin.fail(); if(!OK) { cin.clear(); cin.ignore(); } } while (!OK); cout << var;
3rd Oct 2018, 4:11 PM
Ipang
+ 1
Ha - interesting! I just changed my code like this: int var; do { cin.clear(); cin.ignore(); cin >> var; } while (cin.fail()); And it works as it should. Nice, thank you! :) Anyway... maybe it's just the pythonist in me, but... shouldn't this still be easier? I just want to repeat an input and have to use clear AND ignore every time?
3rd Oct 2018, 4:24 PM
HonFu
HonFu - avatar
+ 1
I played with isdigit() (from ctype) a little bit, but I think you have to scan each byte individually, so it's not actually shorter. A shorter version--if you're okay leaving cin in a fail() state when the loop exits: while(cin>>var); // test and fix cin? Note: Apparently cin/cout are slower than scanf() unless you turn off syncing with the underlying C library: https://stackoverflow.com/questions/1042110/using-scanf-in-c-programs-is-faster-than-using-cin + I link that because the scanf there returns how many inputs it matched and assigned: while(1 == scanf("%d", %var));
3rd Oct 2018, 10:14 PM
Kirk Schafer
Kirk Schafer - avatar
0
Aah, so that's what happened! The first input kind of went through, but then came the freeze and eventually the breakdown. Interesting ... So much to learn! Kirk Schafer so would you say my 5 liner is the most concise or reasonable way to do what I want to do (ask for a number and accept nothing else) or can you think of maybe other ways?
3rd Oct 2018, 8:01 PM
HonFu
HonFu - avatar