Thread: goodbit and failbit of cin

  1. #1
    Registered User
    Join Date
    Sep 2003
    Posts
    133

    goodbit and failbit of cin

    Hi,
    Please take a look at this
    Code:
    int choice;
    
    do{
    
    cin >>choice; 
    
    switch{
    case 1: cout << "Valid choice" <<endl;
    
    case 2: cout<< "leaving loop" << endl;
    
    default: cout << "Invalid choice" << endl;
    }
    
    }while(choice !=2)
    When i input a non integer value such as a char 'a' , this segment of the loop executes infinitely. I believe the cin stream have set failbit because of the incorrect format of input. However, how can i set it back to goodbit? I tried cin.clear() but it didnt work.

    Thanks

  2. #2
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    sorry some error there. here is the amended code

    Code:
    int choice;
     do{ 
    cin >>choice;
    
     switch(choice){ 
    case 1: cout << "Valid choice" <<endl;
    case 2: cout<< "leaving loop" << endl;
     default: cout << "Invalid choice" << endl; 
    }
     }while(choice !=2)

  3. #3
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    urgh!!! I forget the breaks too

    Code:
    int choice;
     do{ 
    cin >>choice;
    
     switch(choice){ 
    case 1: cout << "Valid choice" <<endl;
                 break;
    case 2: cout<< "leaving loop" << endl;
                break;
    
     default: cout << "Invalid choice" << endl; 
                
    }
     }while(choice !=2)

  4. #4
    Registered User
    Join Date
    Sep 2003
    Posts
    135
    When you enter a character instead of an integer cin goes into a failed state. To recover from this you need to clear the stream flags and remove any characters left in the stream, then try again. Here's one simple (but slightly imperfect) way to do this, you get the idea:

    Code:
    #include <iostream>
    #include <limits>
    
    using namespace std;
    
    int main()
    {
        int number;
        cout << "Enter an integer value: " << flush;
        while(!(cin >> number)){
            cin.clear();
            cin.ignore(numeric_limits<int>::max(), '\n');
            cout << "\nInput Invalid. Please Try Again: " << flush;
        }
        cin.ignore(numeric_limits<int>::max(), '\n');
        cout << "You entered: " << number << endl;
    }

  5. #5
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Sorry, i am new to C++ and just have some knowledge of C.So what this mean:

    Code:
    cin.ignore(numeric_limits<int>::max(), '\n');
    To my knowledge, ignore() is used to ignore the next character, unless u specify the number of characters to ignore

  6. #6
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    ok i think i made some understanding.

    Code:
    cin.ignore(numeric_limits<int>::max(), '\n');
    When cin takes in an inproper format, it sets failbit and the input still remains in the buffer stream. After we set it back to good state, we have to discard the inproper input. But how do we know how many characters to discard?

  7. #7
    Registered User
    Join Date
    Sep 2003
    Posts
    135
    This line:

    cin.ignore(numeric_limits<int>::max(), '\n');

    will remove everything from the stream up to the next newline. It look more complicated than it is; that's C++ syntax for you. It's effectively:

    cin.ignore(some_large_number, '\n');

    You could instead use:

    cin.ignore(1000, '\n');

    which doesn't look as frightening, but then you still run the (slight) risk that there will be more than 1000 characters of garbage left in the stream.

    As you rightly suggest, used on its own:

    cin.ignore();

    will remove the next (single) character from the stream.
    Gambling. The new yoga, with cash prizes!

  8. #8
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Code:
    cin.ignore(numeric_limits<int>::max(), '\n');
    Allow me to clarify my understanding:

    So the code above will ignore a max number of characters determined by numeric_limits<int> or unless it encounters the delimiter '\n' first. I tried reading up, but i cant find what does the max() mean. Could you explain? Is it necessary there?

    And also is there any other C++ functions that can flush the stream like fflush() in C,so that i dont have to specify the number of characters to ignore? It seems more efficient this way and i suppose <iomanip> has such function for flushing stream?

    Thanks


  9. #9
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by Raison
    And also is there any other C++ functions that can flush the stream like fflush() in C,so that i dont have to specify the number of characters to ignore?
    Actually you should not be flushing input streams with fflush() in C. fflush() is not defined for input streams according to the standard. Some compilers have allowed it to work but it's one of those bugs waiting to happen if you change compilers.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  10. #10
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    oh my!!! i been flushing since i learned C.

  11. #11
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Shame on you. Go to your corner and think about what you've done!
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  12. #12
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317

    Just a suggestion

    I am just a newbie but wouldn't it be easier just to change the while condition to <=2 so that any other value greater then 2 would exit the loop?

  13. #13
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317

    Conversely

    I guess the other option would be to set choice=2 in the default section of the switch so it would then exit the loop on any invalid output;

  14. #14
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164

    Re: Conversely

    Originally posted by manofsteel972
    I guess the other option would be to set choice=2 in the default section of the switch so it would then exit the loop on any invalid output;
    This would work, and is a better option than above. What if you added 4 as a good option?
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  15. #15
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    i was taught to just do:

    Code:
    while ( cin.get() != '\n' ){}
    to flush the buffer...
    I came up with a cool phrase to put down here, but i forgot it...

Popular pages Recent additions subscribe to a feed