Thread: Problem with cin. Please help me.

  1. #1
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216

    Problem with cin. Please help me.

    In my program, I define a variable of type int, and use cin to input integer into this variable. When my input is like '123' or '123adfd', it works perfectly. But when I input something like 'abc', infinite loop occurs. I know that this infinite loop has something to do with the input buffer. But I just don't know how to clear the input buffer. I had tried many methods but all in vain. I need your help badly. Thanks in advance.

    Here is my code:
    Code:
    #include <iostream>
    #include <limits>
    
    using namespace std;
    
    int main()
    {
    	int var;
    	while ( 1 ) {
    		cout << "Please input an integer." << endl;
    		cin >> var;
    		cin.ignore(numeric_limits<streamsize>::max(), '\n');
    		/*
    		 * I also tried "while ((ch = cin.get()) != '\n' && ch != EOF);" and "cin.sync()",
    		 * but they did no help.
                     *
    		 */
    	}
    
    	return 0;
    }
    
    /* When inputing something like 'abc', it prints "Please input an integer." infinitely.
     *
     * Please input an integer.
     * abc
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * ... ... ...
     *
     */

  2. #2
    Super Moderater.
    Join Date
    Jan 2005
    Posts
    374
    since 'var' is declared as an 'int' it means you can only input numbers.

    Anything else cause the program to crash. If you want to accept all input formats declare it as such.

    Code:
    char var;

  3. #3
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    I just want to accept integers. The problem is I don't know how to deal with the illegal input such as characters. If I know how to flush the input buffer, this problem is solved.

  4. #4
    Super Moderater.
    Join Date
    Jan 2005
    Posts
    374
    try this. It's a bit long winded but if a number is entered it multiplies it by two as an example.

    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        char var[81];
        char number[12]={"0123456789"};
        int cond=1;
        while (cond==1)
        {
        cout<<"Input number>>";
        cin>>var;
        
        int size=strlen(var);
        
        int counter=0;
        for(int j=0; j<size; j++)
        {
        for (int i=0; i<10; i++)
        {
            if (var[j]==number[i])
            {
                counter++;
            }
        }
        }    
    
    
    if (counter==size)
    {
        cout<<"input valid"<<endl;
        cond=0;
        int k;
        k=atoi(var);
        
        cout<<k*2;
    
    
    }   
    } 
    
    int stop;
    cin>>stop;
    }

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    The stream will go into an error state if it is expecting an integer but it only sees characters for example. To move on, you must first clear the error flags by using the clear member function. Then you must get rid of the bad data in the input stream by using the ignore member function. After that, you can attempt to get more input.

    Code:
    int value;
    
    // Ask for integer value, keep on asking until an integer was entered
    cout << "Enter an integer: ";
    while( !(cin >> value) )
    {
        cout << "That's not an integer you idiot!" << endl;
        cin.clear();
        // The 80 is somewhat arbitrary, might want to include <limits> and then use
        // numeric_limits<streamsize>::max() instead
        cin.ignore(80,'\n');
        cout << "Enter an integer: ";
    }
    cout << "The integer you entered is: " << value << endl;
    Possible output:
    Code:
    Enter an integer: qwerty
    That's not an integer you idiot!
    Enter an integer: abc123
    That's not an integer you idiot!
    Enter an integer: 123
    The integer you entered is: 123
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    Quote Originally Posted by hk_mp5kpdw
    The stream will go into an error state if it is expecting an integer but it only sees characters for example. To move on, you must first clear the error flags by using the clear member function. Then you must get rid of the bad data in the input stream by using the ignore member function. After that, you can attempt to get more input.

    Code:
    int value;
    
    // Ask for integer value, keep on asking until an integer was entered
    cout << "Enter an integer: ";
    while( !(cin >> value) )
    {
        cout << "That's not an integer you idiot!" << endl;
        cin.clear();
        // The 80 is somewhat arbitrary, might want to include <limits> and then use
        // numeric_limits<streamsize>::max() instead
        cin.ignore(80,'\n');
        cout << "Enter an integer: ";
    }
    cout << "The integer you entered is: " << value << endl;
    Thank you very much! It works! ^_^
    Thanks all for your help

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I also tried "while ((ch = cin.get()) != '\n' && ch != EOF);"
    That will work, but it's inelegant for C++. It's inelegant for C as well, but a necessary evil in some cases.

    >and "cin.sync()"
    Despite what some confused people will tell you, cin.sync() does not discard leftover characters in the input stream. There was a recent discussion about this where I detailed exactly what sync() does and does not do.

    >it prints "Please input an integer." infinitely
    It's already been said, but you aren't clearing the stream state.
    My best code is written with the delete key.

  8. #8
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    Quote Originally Posted by Prelude
    >I also tried "while ((ch = cin.get()) != '\n' && ch != EOF);"
    That will work, but it's inelegant for C++. It's inelegant for C as well, but a necessary evil in some cases.
    Will it be elegant enough if I define this statement as macro:
    Code:
    #define flush_stdin(ch) while ( ( (ch) = getchar() ) != '\n' && (ch) != EOF );
    Or as a function?

    Quote Originally Posted by Prelude
    >and "cin.sync()"
    Despite what some confused people will tell you, cin.sync() does not discard leftover characters in the input stream. There was a recent discussion about this where I detailed exactly what sync() does and does not do.
    Yes, I read that. I learnt about cin.sync() from that discussion. I also read your post. And learnt that cin.sync() is ambiguous from your post. I used cin.sync() just to had a try because I tried many methods to flush the input buffer but all in vain. But now, thanks to hk_mp5kpdw, I know how to flush the input buffer.

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Will it be elegant enough if I define this statement as macro
    No. Macros should be avoided where possible, especially in C++.

    >Or as a function?
    That just transfers the inelegance.
    My best code is written with the delete key.

  10. #10
    Super Moderater.
    Join Date
    Jan 2005
    Posts
    374
    It don't mean to be pedantic, and probably the problem is easily corrected but what happens if your sample input is?


    Code:
    Enter an integer: 1234abc

    I have compiled and tested this using hk_mp5kpdw's code. The program appears to crash. Please correct me if I'm wrong.

  11. #11
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    It runs correctly in my system.
    I used vc++6 to compile hk_mp5kpdw's code.
    My OS is WinXP

  12. #12
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by treenef
    It don't mean to be pedantic, and probably the problem is easily corrected but what happens if your sample input is?


    Code:
    Enter an integer: 1234abc

    I have compiled and tested this using hk_mp5kpdw's code. The program appears to crash. Please correct me if I'm wrong.
    Running just that small program segment that I posted and the input you specified got me the following:

    Code:
    Enter an integer: 1234abc
    The integer you entered is: 1234
    The trailing "abc" is not converted/extracted from the input stream... which could potentially foul up something else further downstream unless you are careful.

    Was the code you were using to test slightly different in some way? Post it perhaps?
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  13. #13
    Super Moderater.
    Join Date
    Jan 2005
    Posts
    374
    Well if that's the case I probably just have a compiler problem


  14. #14
    Super Moderater.
    Join Date
    Jan 2005
    Posts
    374
    Out of curiousity this is my code, i'm using Devshed,

    Code:
    #include <iostream>
    #include <limits>
    
    using namespace std;
    
    int main()
    {
    	int value;
    
    // Ask for integer value, keep on asking until an integer was entered
    cout << "Enter an integer: ";
    while( !(cin >> value) )
    {
        cout << "That's not an integer you idiot!" << endl;
        cin.clear();
        // The 80 is somewhat arbitrary, might want to include <limits> and then use
        // numeric_limits<streamsize>::max() instead
        cin.ignore(80,'\n');
        cout << "Enter an integer: ";
    }
    cout << "The integer you entered is: " << value << endl;
    int s;
    cin>>s;
    return 0;
    }
    
    /* When inputing something like 'abc', it prints "Please input an integer." infinitely.
     *
     * Please input an integer.
     * abc
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * Please input an integer.
     * ... ... ...
     *
     */

  15. #15
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    #include <iostream>
    #include <limits>
    
    using namespace std;
    
    int main()
    {
        int value;
    
        // Ask for integer value, keep on asking until an integer was entered
        cout << "Enter an integer: ";
        while( !(cin >> value) )
        {
            cout << "That's not an integer you idiot!" << endl;
            cin.clear();
            // The 80 is somewhat arbitrary, might want to include <limits> and then use
            // numeric_limits<streamsize>::max() instead
            cin.ignore(80,'\n');
            cout << "Enter an integer: ";
        }
        cout << "The integer you entered is: " << value << endl;
        int s;
        cin>>s;
        return 0;
    }
    Only problem I see is that last cin. If you enter "1234abc" as input, the cin in the while loop will extract the "1234" and leave the "abc". Then the last cin will try to extract an integer but find only the "abc" which will set the stream into an error state. But... since this is the end of the program that shouldn't really matter much; although if you are using the last cin to pause input before closing the program you won't get to experience that pause because the stream wasn't cleared beforehand
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Words and lines count problem
    By emo in forum C Programming
    Replies: 1
    Last Post: 07-12-2005, 03:36 PM
  2. Input File HELP, weird problem
    By gravity-1 in forum C++ Programming
    Replies: 5
    Last Post: 03-29-2005, 08:43 PM
  3. half ADT (nested struct) problem...
    By CyC|OpS in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 08:37 AM
  4. binary tree problem - help needed
    By sanju in forum C Programming
    Replies: 4
    Last Post: 10-16-2002, 05:18 AM
  5. Problem with cin
    By ErionD in forum C++ Programming
    Replies: 3
    Last Post: 02-19-2002, 11:27 AM