Thread: std::string getline() weirdness

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    85

    Question std::string getline() weirdness

    I'm having issues with the getline() function.

    The code is on a different computer so to save typing time variable names and cout'ed strings are not excact except for the placement of the \n. The code goes something like this:

    Code:
    #include <string>
    #include <otherNeededheader(s)>
    using std::string;
    using std::cout;
    using std::cin or endl or what other crap you see here; //not exact ;-)
    ...
    
    string s1;
    string s2;
    string s3;
    
    cout<<"\n Please enter something: ";
    getline(cin, s1);
    cout<<"\n\n Please enter something else: ";
    getline(cin, s2);
    cout<<"\n Please enter something else: ";
    getline(cin, s3);
    
    cout<<"\nSomething else!!!\n\n";
    
    cout<< "s1: " << s1 <<endl;
    cout<< "s2: " << s2 <<endl;
    cout<< "s3: " << s3 <<endl;
    but the output looks like this:
    Code:
    Please enter something:
    
    Please enter something else: why does user input start here???
    
    Please enter something else: wtf??? wtf???
    
    Something else!!!
    
    s1:
    s2: why does user input start here???
    s3: wtf??? wtf???
    btw 'wtf' stands for 'what the fudge'... in case you were curious

    Can anyone tell me why the program is skipping the first getline command?
    Thank you for being patient with me.
    (I'm using Dev c++ 4.9.9.2)

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Put your newline at the END of what you print, not before it. And you should be using std::endl, not an actual '\n' character.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    85
    I made the changes you said brewbuck
    Code:
    #include <string>
    #include <otherNeededheader(s)>
    using std::string;
    using std::cout;
    using std::cin or endl or what other crap you see here; //not exact ;-)
    ...
    
    string s1;
    string s2;
    string s3;
    
    cout<<"Please enter something: " <<endl;
    getline(cin, s1);
    cout<<"Please enter something else: "<<endl;
    getline(cin, s2);
    cout<<"Please enter something else: "<<endl;
    getline(cin, s3);
    
    cout<<"Something else!!!"<<endl;
    
    cout<< "s1: " << s1 <<endl;
    cout<< "s2: " << s2 <<endl;
    cout<< "s3: " << s3 <<endl;
    but the output looks and works exactly the same :-(

    Code:
    Please enter something:
    Please enter something else: why does user input STILL start here???
    Please enter something else: wtf??? wtf???
    Something else!!!
    
    s1:
    s2: why does user input STILL start here???
    s3: wtf??? wtf???
    any other ideas?

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by A10 View Post
    any other ideas?
    The error is in the code you decided wasn't important.

  5. #5
    Registered User
    Join Date
    Nov 2006
    Posts
    85

    Question

    While trying to find what was causeing the bug i desided to add cin.ignore(1024, '\n'); to see if something was still in the buffer.

    Code:
    #include <string>
    #include <otherNeededheader(s)>
    using std::string;
    using std::cout;
    using std::cin or endl or what other crap you see here; //not exact ;-)
    ...
    
    string s1;
    string s2;
    string s3;
    
    cin.ignore(1024,'\n')
    cout<<"\n Please enter something: ";
    getline(cin, s1);
    cout<<"\n\n Please enter something else: ";
    getline(cin, s2);
    cout<<"\n Please enter something else: ";
    getline(cin, s3);
    
    cout<<"\nSomething else!!!\n\n";
    
    cout<< "s1: " << s1 <<endl;
    cout<< "s2: " << s2 <<endl;
    cout<< "s3: " << s3 <<endl;
    It works but It's only a temporary fix. I'll follow the code during execution to try and find where something's not being completely read or something of that nature.

    Thank you Brewbuck

    p.s.(The reason you don't see the changes from my previous post is because I copied and pasted from the first post.)
    Last edited by A10; 08-17-2007 at 11:20 PM.

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Are you by chance doing a:
    Code:
    	cin >> variable;
    prior to the getline()'s? Because this would leave a newline in the input buffer.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> It works but It's only a temporary fix.
    Adding ignore() is the right way to fix it.

    When you get input from cin >>, it leaves a newline in the input buffer as swoopy said. Calling ignore() ignores that newline. If you don't ignore the newline, then getline reads in the newline and stops; that's what getline is supposed to do. So it reads the newline from the previous input and the string is empty unti lthe next time you call getline.

    A generic solution is to call cin.ignore() after each call to cin >>, but not after each call to getline.

    >> And you should be using std::endl, not an actual '\n' character.
    '\n' is often considered better because it doesn't do an unnecessary flush like endl.

  8. #8
    Registered User
    Join Date
    Nov 2006
    Posts
    85

    Smile

    Yes I am as a matter of fact. I hadn't thought of that. I know cin.getline(someNumber, variable); Will throw away the remaining newline char but would it just be smarter to cin.ignore(1,'\n'); after getting the input?

    Thank you btw


    EDIT: posted before reading Daveds post. Thank You daved for answering my question before I asked it (*twilight zone music*)
    Last edited by A10; 08-17-2007 at 11:49 PM.

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    but would it just be smarter to cin.ignore(1,'\n'); after getting the input?
    If you use cin >> in your code, it is quite possible that there will be more than just a newline in the input stream. The user may have typed several whitespace delimited items, of which only the first is read and the rest left in the stream.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If you want to force your user to hit enter after each entry (and not separate entries by space), then you should ignore a larger number than 1:
    Code:
    cin.ignore(1024, '\n'); // or, to maximize the number of characters ignored, use:
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // #include <limits> and <ios>?
    In some cases you might read in a whitespace separated list of items with cin >> or prefer not to force the user to hit enter after each input. In those cases, you obviously don't want to ignore more than one character, because you could end up ignoring actual user input. You would then want to use cin.ignore() which ignores a single character. These cases are probably rarer, however.

    With cin.ignore() you can never accidentally ignore part of the user's input. With cin.ignore(BIG_NUMBER, '\n') you don't have to worry about extraneous input screwing up your later input. Which you use depends on what you need for your program.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 13
    Last Post: 12-14-2007, 03:34 PM
  2. getline() don't want to work anymore...
    By mikahell in forum C++ Programming
    Replies: 7
    Last Post: 07-31-2006, 10:50 AM
  3. Debugging help
    By cuddlez.ini in forum C++ Programming
    Replies: 3
    Last Post: 10-24-2004, 07:08 PM
  4. DLL and std::string woes!
    By Magos in forum C++ Programming
    Replies: 7
    Last Post: 09-08-2004, 12:34 PM
  5. getline help
    By ProjectsProject in forum C++ Programming
    Replies: 3
    Last Post: 06-14-2004, 11:12 AM