cin wrong input

hi guys I am trying to figure out a way to check for the correct input for example if I type steve in for id it will not work as id is an int,

I thought my code would work but it clearly doesn't

what I thought was happening while input equals false we get trapped in a while loop so we enter steve in so i expect cin.bad() to be set to true so the first if statement shouldn't run yet it seems to for some reason

and I expected the second if statement to run I used cin.clear to clear the state of the stream then ignore to ignore the input

but for some reason the code never gets this far,

what am I doing wrong and clearly I'm mistaken

thanks


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

   vector<info> names;
   int id;
   string name,department;
   int choice;

   bool input1 = false;
        while(!input1){
        cout << "enter your ID" << endl;
        cin >> id;
        if(!cin.bad()){

           input1 = true;
        }
        if(cin.bad()){

            cin.clear();
            cin.ignore();

        }
closed account (E0p9LyTq)
std::basic_ios::bad is used when there is an unrecoverable error with the stream, std::basic_ios::fail can be used to do what you want.

See the example here:
http://en.cppreference.com/w/cpp/io/basic_ios/fail
so whats the difference?

isn't reading a string to an int an unrecoverable error?

ps do you know any good sources I can study the flags of the iostream,I searched online and couldn't find any good sources

thanks
isn't reading a string to an int an unrecoverable error?

Not really. It is possible to recover from this error by clearing the stream error flags and completely cleaning out the input buffer.

Your code is only removing one character from the input buffer, you need to tell ignore() how many characters to remove(usually using numeric limits max) as the numeric value and the end of line character as the optional second parameter.

By the way you can check the status of all the flags by just using the stream name if(std::cin).



> sources I can study the flags of the iostream

https://stdcxx.apache.org/doc/stdlibug/29-1.html
https://stdcxx.apache.org/doc/stdlibug/29-2.html

It is canonical to check for the success or failure of attempted input by using the returned (reference to the) stream as the condition in if/loop statements.

See: http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool
This operator makes it possible to use streams and functions that return references to streams as loop conditions, resulting in the idiomatic C++ input loops such as
while(stream >> value) {...} or while(getline(stream, string)){...}.
Such loops execute the loop's body only if the input operation succeeded.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>

int get_int()
{
    int value ;
    if( std::cin >> value ) return value ; // success: an int was read

    // badly formed input: failed to read an int
    std::cout << "please enter en integer: " ; // inform the user
    std::cin.clear() ; // clear the failed state of the stream
    std::cin.ignore( 1000000, '\n' ) ; // extract and discard the bad input
    return get_int() ; // try again
}

int get_int( int minv, int maxv )
{
    int value = get_int() ;
    if( value >= minv && value <= maxv ) return value ;

    // out of range
    std::cout << "please enter a value in [" << minv << ", " << maxv << "]: " ;
    return get_int(minv,maxv) ;
}

int main()
{
    std::cout << "id [0,999]?: " ;
    const int id = get_int(0,999) ;
    std::cout << "id is " << id << '\n' ;
}
thanks guys

I tried ignoring a large number followed by a newline as the params to ignore but it doesn't seem to work the way I expected it pretty much just goes to a new line and waits for input

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


while(!input1){

            cout << "enter id" << endl;
            cin >> id;

            if(cin.fail()){

                cin.clear();
                cin.ignore();
            }else{

                 input1 = true;

            }
        }
also another snippet of code to explain my question below

another question relating to this is what would cause a stream to go into an unrecoverable error or the cin.bad() to be true?

and for some reason when I print out the failbit in both cases it prints 4,why 4? and I thought that it would be 0 if the read is successful yet it still prints 4

thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

while(!input1){
        cout << "enter your ID" << endl;
        if(cin >> id){

            cout << cin.failbit << endl;
            input1 = true;
        }else{
           cout << cin.failbit << endl;
           cin.clear();
           cin.ignore(10000, '\n');
        }
        }

> when I print out the failbit in both cases it prints 4,why 4?

std::ios_base::failbit is an implementation defined constant (BitmasType)
http://en.cppreference.com/w/cpp/io/ios_base/iostate
http://en.cppreference.com/w/cpp/concept/BitmaskType

To check if the failbit or badbit is set, we can use std::cin.fail()
http://en.cppreference.com/w/cpp/io/basic_ios/fail

Though, in this case,
1
2
if(cin >> id) { /* there was no input failure: cin.fail() == false */ } 
else { /* input failure: cin.fail() == true */ }
already performs that check.
thnaks JL
int i;
cin>>i;
if(cin.fail()) {
// do error handling here
}

syntax for the c cin !!
http://www.cetpainfotech.com/technology/c-language-training
Topic archived. No new replies allowed.