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

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    124

    Two problems with std::cin.getline()

    I am having two issues with the std::cin.getline() function.

    Here is the relevant portion of my code:
    Code:
    std::cout << "Enter administrator password to unlock the database file" << std::endl;
    		
    while (!datafileVerified)
    {
        std::cin.getline(adminPassword, MAX_PASSWORD_LENGTH+1);
        passLength = std::cin.gcount() - 1;
        datafileVerified = verifyDatafile(adminPassword);
        if (!datafileVerified) { std::cout << "Incorrect admin password, try again" << std::endl; }
    }
    MAX_PASSWORD_LENGTH is 16 so cin.getline() should accept 17 characters (16 + NULL).

    First question:
    When I input 16 characters or fewer cin.gcount() - 1 returns the correct number of characters (I don't want the NULL counted, hence the -1). So if I put in 16 characters gcount() - 1 gives returns 16. If; however, I input 17+ characters then gcount() -1 always returns 15. I put in more and it gives me less. What gives?

    Second question:
    When I put in an incorrect password, the call to verifyDatafile will fail and return 0. The variable datafileVerified is initialized to 0. If I input 16 or fewer characters this block of code works as expected, if the password is incorrect it continues to prompt the user for the password again. If; however, I input 17+ characters it skips the cin.getline() every time it goes through the loop and simply loops infinitely! What gives?

    Thanks.

  2. #2
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Why don't you just use the getline() function and use std::string instead anyway?

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you give getline 17 as a parameter, it will not read more than 16 characters in. And, as you correctly noticed, 16-1 equals 15.

    Also, if you type in extra characters, the characters not read in will still be there in the next iteration of the while loop. (You shouldn't see an infinite loop -- 16 to 31 characters should give you two iterations, 32 to 47 three, etc.)

  4. #4
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    Quote Originally Posted by tabstop View Post
    If you give getline 17 as a parameter, it will not read more than 16 characters in. And, as you correctly noticed, 16-1 equals 15.

    Also, if you type in extra characters, the characters not read in will still be there in the next iteration of the while loop. (You shouldn't see an infinite loop -- 16 to 31 characters should give you two iterations, 32 to 47 three, etc.)
    Ok, I had an inkling that might be the issue. Is there anyway to flush stdin to get rid of any extra input?

  5. #5
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    I am not trying to say something discouraging, but given how you seem to have a lot of confusion about char buffers why not just use std::strings? Its more robust for this type of application anyway. Unless 16 is a magic number for some sort of encryption you have implemented (perhaps you have colaberated with Kevin and his encryption technique that would require 5000+ years for a large amount of data to be decrypted).

  6. #6
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    Quote Originally Posted by master5001 View Post
    I am not trying to say something discouraging, but given how you seem to have a lot of confusion about char buffers why not just use std::strings? Its more robust for this type of application anyway. Unless 16 is a magic number for some sort of encryption you have implemented (perhaps you have colaberated with Kevin and his encryption technique that would require 5000+ years for a large amount of data to be decrypted).
    I've already dedicated too much time to this program to replace all my char buffers with std::string. I know how char buffers work. I was mainly hoping there was a way to discard extraneous input from stdin after a call to cin.getline().

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    cin.ignore()

  8. #8
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    Quote Originally Posted by tabstop View Post
    cin.ignore()
    cin.ignore() asks for a number of characters to ignore. Is it safe to pass a huge number like INT_MAX to it?

  9. #9
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by maxhavoc View Post
    cin.ignore() asks for a number of characters to ignore. Is it safe to pass a huge number like INT_MAX to it?
    I believe that if you pass no parameters to std::istream::ignore(), it uses the default parameters of 1, and EOF respectively, and somehow this has the effect of ignoring all remaining data.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Wouldn't know why not. Be sure to use it only when you know there's extra input, though.

  11. #11
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    Quote Originally Posted by tabstop View Post
    Wouldn't know why not. Be sure to use it only when you know there's extra input, though.
    Er...I can never *know* there's going to be extra input. I mean...there has to be a way to accept input safely in C++. There has to be a way to allow for input into a buffer with a fixed upper bound that doesn't break when someone tries to overflow it. I mean...right? It has to exist! I thought cin.getline() was the answer. What should I use instead?

  12. #12
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Such things can always be tried, you know. Particularly when you ask a question that is somewhere between obvious and implementation specific.

  13. #13
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    Quote Originally Posted by master5001 View Post
    Such things can always be tried, you know. Particularly when you ask a question that is somewhere between obvious and implementation specific.
    The point of asking for help in a forum is to gain the benefit of peoples' experiences. I'm not going to input 2 million some odd characters to see if it breaks if someone else already knows the answer.

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    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.)

  15. #15
    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'?

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