Thread: Two problems with std::cin.getline()

  1. #16
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    This has always served me well.

    Code:
    ignore((unsigned)-1, '\n');
    Though in your case, perhaps

    Code:
    ignore(MAX_PASSWORD_LENGTH, '\n');
    Would make the most sense.

  2. #17
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    Quote Originally Posted by tabstop View Post
    You need to know whether the \n was found and discarded, so you want to use the input operation that doesn't actually discard the \n character. That input operation is "get". (Of course, this means that you have to discard the \n yourself, but hey.)
    Ok, when I replace getline with get I no longer need to decrement gcount by 1 to get the actual number of characters read however I still have the same issue with the infinite loop when the user provides too much input. How am I supposed to test for the '\n'?

  3. #18
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    master5001, the problem with that approach is that allows ONLY 16 characters, not up to and including 16 characters.

  4. #19
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by maxhavoc View Post
    Ok, when I replace getline with get I no longer need to decrement gcount by 1 to get the actual number of characters read however I still have the same issue with the infinite loop when the user provides too much input. How am I supposed to test for the '\n'?
    If the string ends with a \n, there's no new input so don't do anything.
    If the string doesn't end with an \n, there's something still in the buffer.
    Note you have to do this before stripping off the \n to compare with your password. (I would say, if there's more input in the stream, the input is automatically wrong, ignore and continue; otherwise check as above.)

  5. #20
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    Quote Originally Posted by tabstop View Post
    If the string ends with a \n, there's no new input so don't do anything.
    If the string doesn't end with an \n, there's something still in the buffer.
    Note you have to do this before stripping off the \n to compare with your password. (I would say, if there's more input in the stream, the input is automatically wrong, ignore and continue; otherwise check as above.)
    So what you're saying is do something like:
    Code:
    cin.get(inputString, 16);
    if (inputString[cin.gcount()] == '\n')
       good;
    else
       bad;

  6. #21
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    >> master5001, the problem with that approach is that allows ONLY 16 characters, not up to and including 16 characters.

    Code:
    ignore(MAX_PASSWORD_LENGTH+1, '\n');
    The point is, even if you don't care if there are a total of 1,342,312,678,793,163 '\n' characters put into the text box, you can only possibly see so many at one given time. Thus there is no need to use MAX_INT or (unsigned)-1 or any other exceedingly large numeric value. MAX_CHAR is already more than the buffer can hold. Thus cin won't even need to look past MAX_PASSWORD_LENGTH + 1.

  7. #22
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by maxhavoc View Post
    So what you're saying is do something like:
    Code:
    cin.get(inputString, 16);
    if (inputString[cin.gcount()] == '\n')
       good;
    else
       bad;
    Well, sort of; by "good" I mean call the verifier function thing and by "bad" I mean call ignore. And that 16 needs to be 18 (one for the new line, and one for the \0).

  8. #23
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by master5001 View Post
    >> master5001, the problem with that approach is that allows ONLY 16 characters, not up to and including 16 characters.

    Code:
    ignore(MAX_PASSWORD_LENGTH+1, '\n');
    The point is, even if you don't care if there are a total of 1,342,312,678,793,163 '\n' characters put into the text box, you can only possibly see so many at one given time. Thus there is no need to use MAX_INT or (unsigned)-1 or any other exceedingly large numeric value. MAX_CHAR is already more than the buffer can hold. Thus cin won't even need to look past MAX_PASSWORD_LENGTH + 1.
    What buffer?

  9. #24
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    tabstop, that is incredibly obnoxious. Is that really the lengths that you need to go to so that you can accept input safely from the console? Every single time input is required? No wonder there are so many buffer overflows in C/C++ code, if it's that hard just to do something like accept input safely. There really needs to be a smart function that handles that for the programmer.

  10. #25
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    adminPassword...

  11. #26
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    It is not that big of a deal, maxhavoc. If you are using cin.get() like tabstop has up there you are simply using MAX_PASSWORD_LENGTH instead of your magic number. And how else would you have someone know when to stop reading?

  12. #27
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by maxhavoc View Post
    tabstop, that is incredibly obnoxious. Is that really the lengths that you need to go to so that you can accept input safely from the console? Every single time input is required? No wonder there are so many buffer overflows in C/C++ code, if it's that hard just to do something like accept input safely. There really needs to be a smart function that handles that for the programmer.
    The non-obnoxious way is
    Code:
    std::string bob;
    getline(std::cin, bob);

  13. #28
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    As I also mentioned before, you can also use the std::getline() function in conjunction with std::string. Which would entirely circumvent the parts which you seem to have the hardest time grasping: the idea of a fixed size buffer.

  14. #29
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by master5001 View Post
    adminPassword...
    Well, but the whole point of ignore is that the only place I know the input isn't going is adminPassword.

  15. #30
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Quote Originally Posted by tabstop View Post
    The non-obnoxious way is
    Code:
    std::string bob;
    getline(std::cin, bob);
    Thank you Its nice to have someone second that opinion.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. No clue how to make a code to solve problems!
    By ctnzn in forum C Programming
    Replies: 8
    Last Post: 10-16-2008, 02:59 AM
  2. C Pointers Problems
    By mhelal in forum C Programming
    Replies: 8
    Last Post: 01-10-2007, 06:35 AM
  3. Rendering problems (DirectX?)
    By OnionKnight in forum Tech Board
    Replies: 0
    Last Post: 08-17-2006, 12:17 PM
  4. contest problems on my site
    By DavidP in forum Contests Board
    Replies: 4
    Last Post: 01-10-2004, 09:19 PM
  5. DJGPP problems
    By stormswift in forum C Programming
    Replies: 2
    Last Post: 02-26-2002, 04:35 PM