Thread: Phantom input in cin (C++)

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    3

    Question Phantom input in cin (C++)

    Hello all -- I'm pretty new to C++ and C and can't figure out how to reliably detect and work around the mystery input that seems to get trapped in cin. Without any discernible pattern, VC++ seems to find something in the input buffer and thus skips the next input statement (it happens with >>, get() and getline()).
    Code:
    system("cls");
    
    cout<<"                                   ADD EQUIPMENT\n"
           <<"\n\n     For non-applicable items, enter 0 or N\n";
    	
    cout<<"\n     Enter Name: "; getline(cin, response);
    strcpy(newRecord.chrName, response.c_str());
    cout<<"\n     Enter Weight Capacity (if applicable): "; cin>>newRecord.iCapacity;
    I've tried the various get() and getline() buffer-flushing code snippets, but the program stops and waits for input. I need a way to check the input buffer without the program stopping and waiting for the input. I've tried get(), getline(), peek() and various combinations of them and haven't had any luck.

    The method works the first time, but the second time the getline() is skipped, as if there were input.

    Any help would be greatly appreciated. Thanks for all the great hints I've already gotten here!

  2. #2
    Master of the Universe! velius's Avatar
    Join Date
    Sep 2003
    Posts
    219
    You call cin.ignore() with the number of bytes to discard.
    So if the \n character is left behind you call cin.ignore(1).
    Likewise if the number of characters differs then you modify the 1 to the appropriate number.
    While you're breakin' down my back n'
    I been rackin' out my brain
    It don't matter how we make it
    'Cause it always ends the same
    You can push it for more mileage
    But your flaps r' wearin' thin
    And I could sleep on it 'til mornin'
    But this nightmare never ends
    Don't forget to call my lawyers
    With ridiculous demands
    An you can take the pity so far
    But it's more than I can stand
    'Cause this couchtrip's gettin' older
    Tell me how long has it been
    'Cause 5 years is forever
    An you haven't grown up yet
    -- You Could Be Mine - Guns N' Roses

  3. #3
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    in your case, the getline() function is leaving the user's return character in the input stream... just throw cin.ignore(1); after the getline() and before the next cin.
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  4. #4
    Registered User
    Join Date
    Dec 2003
    Posts
    3
    Many thanks for the replies. My problem is that if there is nothing in the buffer, the cin.ignore() waits for input. Also, it doesn't happen every time; the first pass is fine, but if I call the method a second time, it happens. So I need some kind of condition to check that doesn't wait for the user to input something if nothing is already in the stream.

    The forbidden fflush(stdin) seems to be working for the moment.

  5. #5
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    If you are using VC++ 6.0 and getline, make sure you fix the bug in the VC++ standard library implementation. Check out this site and scroll down to the part about <string>

    http://www.dinkumware.com/vc_fixes.html

    or look at this one

    http://support.microsoft.com/default...;en-us;Q240015

    Once you apply their fix, you should be able to use getline without the ignore.

  6. #6
    Registered User
    Join Date
    Dec 2003
    Posts
    3
    Thanks again, I had that fix in. I saw the others though and was shocked (if not surprised) at the number of them!

  7. #7
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    The stadard streams are inherently blocking. That is your program will wait for input. The nature of stdin is also that your program will generally not see any input untill the user has hit newline. If you do not have the VC++ bug mentioned by jlou then you do not need an ignore after getline() but you still have a newline after reading the int. If leading whitespace is not significant to responce(and it looks like you would want to trim that anyway) you can use

    cin >> newRecord.iCapacity >> ws

    ws is a manipulator that eats whitespace and throws it away.

    In general user friendly keyboard input requires delving into non-portable teritory. Usually a non-blocking kbhit() and getkey(), conio.h tends to be the most widely available.

    You also are using strcpy, rather than strncpy, and you are not checking the failbit from the integer read. Both major sources of confusing silent errors.

  8. #8
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    i've never heard of ws... where is it from?
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  9. #9
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    Originally posted by major_small
    i've never heard of ws... where is it from?
    I beleve it's in <iostream> or else <iomanip>. manipulators are one of the cool things about streams.

  10. #10
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398

    ws is in <istream>

    ... which means it is included in <iostream>.

    I found this from dinkumware.com, one of my favorite references:
    ws
    template class<Elem, Tr>
    basic_istream<Elem, Tr>& ws(basic_istream<Elem, Tr>& istr);

    The manipulator extracts and discards any elements ch for which use_facet< ctype<Elem> >( getloc()). is( ctype<Elem>::space, ch) is true.

    The function calls setstate(eofbit) if it encounters end-of-file while extracting elements. It returns istr.
    Well... maybe not that easy to understand... but the above definition is from <istream>.

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I usually use rdbuf()->in_avail() together with ignore().
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem grabbing k/b input
    By falcon9 in forum C Programming
    Replies: 2
    Last Post: 10-28-2007, 11:47 AM
  2. cin input error
    By justlivelife15 in forum C++ Programming
    Replies: 4
    Last Post: 06-18-2007, 11:29 AM
  3. Trouble with a lab
    By michael- in forum C Programming
    Replies: 18
    Last Post: 12-06-2005, 11:28 PM
  4. need help with some input
    By blindleaf in forum C Programming
    Replies: 2
    Last Post: 03-16-2003, 01:50 PM
  5. c++ string input
    By R.Stiltskin in forum C++ Programming
    Replies: 4
    Last Post: 02-22-2003, 04:25 PM