cin input (newbie question)

Discussion in 'C++' started by B. Fletcher, Apr 8, 2004.

  1. B. Fletcher

    B. Fletcher Guest

    Hi
    I'm currently converting a console Java application into C++, and I am
    having a problem. I am a newbie at C++ and any help would be apreaciated.

    My code says;
    int marbles;
    ....
    cin >> marbles;
    If I type a word into the program, the program goes into an infinite loop. I
    know this is because I'm using the >> version of cin, but the alternatives
    dont allow for:
    If the user doesn't enter an int, I want the program to display a promt to
    the user. But if there is an error/EOF while reading, I want a different
    prompt displayed.

    Btw, I am using MingW g++.exe to compile. the version of MingW I am using
    came with Borland C++ BuilderX.

    Does anyone have any suggestions on the method I can use?
    Any help would be greatly appreaciated.

    B.
    --
    /*Real programmers write machine code.
    Smart programmers write Java. :)*/
    B. Fletcher, Apr 8, 2004
    #1
    1. Advertising

  2. B. Fletcher

    Sharad Kala Guest

    "B. Fletcher" <> wrote in message
    news:...
    > Hi
    > I'm currently converting a console Java application into C++, and I am
    > having a problem. I am a newbie at C++ and any help would be apreaciated.
    >
    > My code says;
    > int marbles;
    > ...
    > cin >> marbles;
    > If I type a word into the program, the program goes into an infinite loop. I
    > know this is because I'm using the >> version of cin, but the alternatives
    > dont allow for:
    > If the user doesn't enter an int, I want the program to display a promt to
    > the user. But if there is an error/EOF while reading, I want a different
    > prompt displayed.


    Look at the following -
    cin.good ()
    cin.clear ()
    and cin.ignore().

    Basically cin goes into a fail state on any kind of errors. So you need to set
    the stream into good state again and ignore the extra unwanted characters.

    -Sharad
    Sharad Kala, Apr 8, 2004
    #2
    1. Advertising

  3. Sharad Kala wrote:
    >
    > "B. Fletcher" <> wrote in message
    > news:...
    > > Hi
    > > I'm currently converting a console Java application into C++, and I am
    > > having a problem. I am a newbie at C++ and any help would be apreaciated.
    > >
    > > My code says;
    > > int marbles;
    > > ...
    > > cin >> marbles;
    > > If I type a word into the program, the program goes into an infinite loop. I
    > > know this is because I'm using the >> version of cin, but the alternatives
    > > dont allow for:
    > > If the user doesn't enter an int, I want the program to display a promt to
    > > the user. But if there is an error/EOF while reading, I want a different
    > > prompt displayed.

    >
    > Look at the following -
    > cin.good ()
    > cin.clear ()
    > and cin.ignore().
    >
    > Basically cin goes into a fail state on any kind of errors. So you need to set
    > the stream into good state again and ignore the extra unwanted characters.
    >


    To the OP:

    That's one way to do it.
    Another way would be to not input into an int at all.
    Read everything as a string and figure out if the string
    entered contains only digits (or whatever you want the user
    to enter), and do the conversion on your own. (eg. by using
    a string stream).

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Apr 8, 2004
    #3
  4. B. Fletcher

    red floyd Guest

    "B. Fletcher" <> wrote in message news:<>...
    > Hi
    > I'm currently converting a console Java application into C++, and I am
    > having a problem. I am a newbie at C++ and any help would be apreaciated.
    >
    > My code says;
    > int marbles;
    > ...
    > cin >> marbles;
    > If I type a word into the program, the program goes into an infinite loop. I
    > know this is because I'm using the >> version of cin, but the alternatives
    > dont allow for:
    > If the user doesn't enter an int, I want the program to display a promt to
    > the user. But if there is an error/EOF while reading, I want a different
    > prompt displayed.


    operator>> allows you to check the result.

    if (cin >> marbles)
    {
    // I got marbles!
    }
    else if (cin.eof())
    {
    // EOF
    }
    else // disclaimer, I can't remember all the statuses for std::istream
    {
    // error or bad input
    }
    red floyd, Apr 8, 2004
    #4
  5. B. Fletcher wrote:

    > Hi
    > I'm currently converting a console Java application into C++, and I am
    > having a problem. I am a newbie at C++ and any help would be apreaciated.
    >
    > My code says;
    > int marbles;
    > ...
    > cin >> marbles;
    > If I type a word into the program, the program goes into an infinite loop.


    Robust input handling usually means reading a line at a time (as others
    have suggested). The problem (well, one of them) with >> is that it
    tends to handle surprising input in surprising ways. You've discovered
    one such case. Also, consider what happens if I enter multiple (valid)
    input items on one line. The next time a prompt should appear, my old
    input is already available and will be used instead of the program
    waiting for new input.

    You can work around the problems with >> (or ignore them, if you don't
    need robust input handling), but you may find it easier to just read an
    entire line, check the validity of it, then interpret the data
    appropriately. Use std::getline(std::istream &, std::string &) for
    reading a line.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Apr 8, 2004
    #5
  6. "B. Fletcher" <> wrote in message
    news:...
    > Hi
    > I'm currently converting a console Java application into C++, and I am
    > having a problem. I am a newbie at C++ and any help would be apreaciated.
    >
    > My code says;
    > int marbles;
    > ...
    > cin >> marbles;
    > If I type a word into the program, the program goes into an infinite loop.

    I
    > know this is because I'm using the >> version of cin, but the

    alternatives
    > dont allow for:
    > If the user doesn't enter an int, I want the program to display a promt to
    > the user. But if there is an error/EOF while reading, I want a different
    > prompt displayed.
    >
    > Btw, I am using MingW g++.exe to compile. the version of MingW I am using
    > came with Borland C++ BuilderX.
    >
    > Does anyone have any suggestions on the method I can use?
    > Any help would be greatly appreaciated.


    I use this. It's always worked for what I need, maybe not in your case
    though.

    cin >> marbles;

    while(cin.peek() != 10)
    {
    cin.clear();
    cin.ignore(80, '\n');

    cout << "Sorry, the number you entered was not valid." << endl;
    cout << "Please enter an integer: ";
    cin >> marbles;
    }


    Adrian
    Adrian Parker, Apr 9, 2004
    #6
  7. Adrian Parker wrote:
    >
    >
    > I use this. It's always worked for what I need, maybe not in your case
    > though.
    >
    > cin >> marbles;
    >
    > while(cin.peek() != 10)
    > {
    > cin.clear();
    > cin.ignore(80, '\n');
    >
    > cout << "Sorry, the number you entered was not valid." << endl;
    > cout << "Please enter an integer: ";
    > cin >> marbles;
    > }


    Both of the magic numbers in your code are ill-advised. If you want to
    look for a newline, just use '\n'. If you want to discard all input up
    to a delimiter, use std::numeric_limits<std::streamsize>::max(). Or at
    least something a lot larger than 80... (the streamsize max() suggestion
    acts like infinity for the ignore() function).

    I think you could probably do better with something like this:

    while (!(cin >> marbles))
    {
    if (cin.eof() || cin.bad())
    {
    // No sense in trying to continue.
    throw "something reasonable";
    }

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

    // Repeat prompt here.
    }

    This reveals a few of the problems with the above code. In particular,
    it continued to prompt even if end-of-file is encountered. This should,
    I believe, put it in an infinite loop. Continuing when badbit has been
    set is also questionable.

    Although, my version doesn't handle extra data on the input line the way
    yours does. That would take a bit more work.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Apr 9, 2004
    #7
  8. "Kevin Goodsell" <> wrote in message
    news:CNpdc.2743$...
    > Adrian Parker wrote:
    > >
    > >
    > > I use this. It's always worked for what I need, maybe not in your case
    > > though.
    > >
    > > cin >> marbles;
    > >
    > > while(cin.peek() != 10)
    > > {
    > > cin.clear();
    > > cin.ignore(80, '\n');
    > >
    > > cout << "Sorry, the number you entered was not valid." << endl;
    > > cout << "Please enter an integer: ";
    > > cin >> marbles;
    > > }

    >
    > Both of the magic numbers in your code are ill-advised.


    When will the newline character in an int not be 10?


    > If you want to
    > look for a newline, just use '\n'. If you want to discard all input up
    > to a delimiter, use std::numeric_limits<std::streamsize>::max(). Or at
    > least something a lot larger than 80... (the streamsize max() suggestion
    > acts like infinity for the ignore() function).
    >
    > I think you could probably do better with something like this:
    >
    > while (!(cin >> marbles))
    > {
    > if (cin.eof() || cin.bad())


    I'm told that cin.eof is a bad practice, although I do not understand why.


    > {
    > // No sense in trying to continue.
    > throw "something reasonable";
    > }
    >
    > cin.clear();
    > cin.ignore(numeric_limits<streamsize>::max(), '\n')
    >
    > // Repeat prompt here.
    > }
    >
    > This reveals a few of the problems with the above code. In particular,
    > it continued to prompt even if end-of-file is encountered. This should,
    > I believe, put it in an infinite loop. Continuing when badbit has been
    > set is also questionable.


    If it's user input though, why worry about EOF? The user can as easily hit
    C-c as C-z (Windows bindings anyway).


    Adrian
    Adrian Parker, Apr 9, 2004
    #8
  9. "Kevin Goodsell" <> wrote in message
    news:CNpdc.2743$...
    > Adrian Parker wrote:


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


    I like this. Thank you.



    Adrian
    Adrian Parker, Apr 9, 2004
    #9
  10. Adrian Parker wrote:

    >
    > When will the newline character in an int not be 10?


    On any system that uses a character set in which it is something else.
    Why assume it will be 10? It only serves to decrease portability and
    clarity.

    >>
    >>I think you could probably do better with something like this:
    >>
    >>while (!(cin >> marbles))
    >>{
    >> if (cin.eof() || cin.bad())

    >
    >
    > I'm told that cin.eof is a bad practice, although I do not understand why.
    >


    It's bad to loop on cin.eof(), but checking it after an error has
    occurred is good. You don't loop on it because it may not be true at the
    time you expect it to be. After reading the last character, the flag
    might not yet be set. Instead, it will be set after you attempt to read
    one more (non-existent) character.

    There's a FAQ entry about this, if you haven't read it:

    http://www.parashift.com/c -faq-lite/input-output.html#faq-15.5


    >
    >
    > If it's user input though, why worry about EOF? The user can as easily hit
    > C-c as C-z (Windows bindings anyway).
    >


    If you think it's acceptable for your program to force the user to
    terminate the program in an unusual way, and enter an infinite loop if
    they try to terminate the input in the usual way, or if they pipe in a
    file, then I suppose you can do that. I consider it sloppy and wouldn't
    do it myself, nor would I want to use a program that behaves that way.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Apr 9, 2004
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. TaiwanNoWhere

    cin and cin.clear() problem

    TaiwanNoWhere, Oct 13, 2003, in forum: C++
    Replies:
    8
    Views:
    4,084
    P.J. Plauger
    Oct 17, 2003
  2. Chris Mantoulidis

    std::cin.ignore() and std::cin.clear()

    Chris Mantoulidis, Jan 6, 2004, in forum: C++
    Replies:
    5
    Views:
    17,118
    Kevin Saff
    Jan 6, 2004
  3. mark
    Replies:
    4
    Views:
    604
    Prateek R Karandikar
    Jun 21, 2004
  4. Aleander

    cin and cin.getline()

    Aleander, Mar 6, 2005, in forum: C++
    Replies:
    5
    Views:
    8,644
    Alex Vinokur
    Mar 6, 2005
  5. Fernando
    Replies:
    4
    Views:
    1,630
    Fernando
    Nov 16, 2011
Loading...

Share This Page