#1
  1. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,481
    Rep Power
    15

    cin.getline(): another VC++6.0 bug?


    Hi,

    This time I'm having a problem with cin.getline(). The user enters a number and then is supposed to enter some text, but the program won't pause for the user to input the text. My interpretation is that the first cin leaves the \n in the input stream, so when cin.getline() goes to work it sees the \n in the stream and the program continues on. Is that normal operation?

    Code:
    int main()
    {
    	int number=0;
    	cout<<"Enter a number: ";
    	cin>>number;
    
    	int max = 19;
    	char text[20];
    	
    	cout<<"Enter some text: ";
    	cin.getline(text, max);
    
    	cout<<"\nNumber: "<<number<<endl;
    
    	return 0;
    }
    Last edited by 7stud; February 20th, 2003 at 04:19 AM.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    190
    I think i read another thread here some time ago explaining that this is NOT expected behaviour but a bug.
    Search here in this forum, i am sure the therad had the answer...

    [edit]
    i found it.... getline(cin, text)
    [/edit]
    Last edited by M.Hirsch; February 20th, 2003 at 01:41 PM.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,481
    Rep Power
    15
    Hi,

    The getline() function is defined in the <string> header file while cin.getline() is defined in the <iostream> header file. In addition, the problem is different: with the getline() problem, I have to hit return twice to get the code to read in the data. The problem I'm having with cin.getline() is that it won't pause at all to let me enter data. To me it seems like two different functions and two different problems.
  6. #4
  7. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,641
    Rep Power
    4247
    This is NOT a bug, it's a feature of C++ :). I duplicated your problem using a gcc compiler. The problem is as follows. The first cin reads everything upto the \n, but leaves it behind in the buffer. The next cin reads what was left in the buffer (i.e. the \n) and assigns it to the variable text. For example, when prompted to enter a number, if you entered:
    12 This is a test
    Then 12 gets assigned to number and "This is a test" gets assigned to text. So how would you fix it?? Something like this possibly:
    Code:
    int main()
    {
      int number=0;
      cout<<"Enter a number: ";
      cin>>number;
    
      if (cin.peek() == '\n')
        cin.ignore(1);
    
      int max = 19;
      char text[20];
    
      cout<<"Enter some text: ";
      cin.getline(text, max);
    
      cout<<"\nNumber: "<<number<<endl;
      cout<<"\nText: "<<text<<endl;
    
      return 0;
    }
    Hope this helps!
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    190
    In that thread you tell that the same problem happens with cin.getline() too. i guess you would have to modify this one too.

    On the other hand - did you make the modifications to the header file? this probably is the cause for the doubled "\n" now :rolleyes:

    IMHO the problem should be searched for somewhere else. All implementations of getline() should be the same and inherit from the "standard" stream class. This is probably where the real error is in....

    just a guess from a non-VC++ user. and sorry for the flame. i removed it.

    to scorpions: you call it a feature. but why? shouldnīt all Stream.getline() methods behave the same way?
    Last edited by M.Hirsch; February 20th, 2003 at 01:42 PM.
  10. #6
  11. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,641
    Rep Power
    4247
    >> shouldnīt all Stream.getline() methods behave the same way?
    They all do behave the same way. Consider that you were reading input from a file, instead of from a keyboard. cin >> number reads all the digits till it hits a non-digit character (or EOF). Then it leaves the remaining input to be read by the next stream call. So if you entered this:
    12,This is a test
    when prompted to enter a number, then 12 would get assigned to number and the remaining (i.e. ",this is a test") would be left in the input buffer. The next cin call would pick up what it can. If you used cin >> text instead of cin.getline(text, max), then text would get assigned the string ",This" because it would treat the space after ",This " as the end of the input for text and leave the rest of the input buffered for the next cin call.

    Hope this clears things up somewhat :)
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    190
    Not sure if i understood you correctly... Is the problem (in other words) this:

    - if you use String.getline() it knows it has to read a string
    - if you use cin.getline() it doesnīt know so the delimiter wonīt be part of the output (input)

    :confused:
  14. #8
  15. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,641
    Rep Power
    4247
    Hehe, actually there's no problem with either. Let me try explaining it again.

    This line:
    cin >> number;
    is what is causing the issue. If you typed input like this:
    15[enter key]
    When cin is reading a number, it will read all the digits from the input stream until it hits a non-digit (in this case, '\n'). Then it leaves the non-digit in the input stream. Hence the '\n' is left behind in the input stream. The next cin.getline() or string.getline() or whatever will pick up from where the last cin left off. Since getline() uses '\n' as a terminator by default, guess what it gets when it reads the stream. You got it -- the \n from when you entered the number. Hence it reads it and believes that it has the input for the cin.getline(text, max);. You could also use the getline() from string and the same issue will occur.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    190
    Thanks for the explanation. I think i did understand it in your last post then.

    Correcting myself: :)
    if you use getline() to read a number, it will leave "\n" in the stream because it is not a digit.
    if you use getline() to read a string, it will read the "\n" too because it is valid for strings.

    right?
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,481
    Rep Power
    15
    Thanks for all the help. M. Hirsh--no offense taken. I wanted to find out what the parameter was for cin.ignore(), so I searched "cin.ignore" on google and came up with this great link to "Tips and Tricks for C++ I/O" which explains the whole thing too:

    http://www.augustcouncil.com/~tgibso...al/iotips.html

    You guys should bookmark that link for the next newbie.


    "On the other hand - did you make the modifications to the header file?"

    I couldn't figure out how to get into the "system" header file, so I was unable to make the modifications.
    Last edited by 7stud; February 20th, 2003 at 02:27 PM.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    190
    isnīt it funny that many people here call me "hirsh" though my name states "M.Hirsch"? - no offense taken either! ;)

    just something i encountered quite often here recently... is "hirsh" an english word? And if so, what does it say?
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,481
    Rep Power
    15
    is "hirsh" an english word?

    Not, that I know of. I usually copy and paste people's user names, so I don't have to figure out the spelling, but for some reason I didn't do that this time. My apologies.
  24. #13
  25. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,641
    Rep Power
    4247
    Originally posted by M.Hirsch
    Thanks for the explanation. I think i did understand it in your last post then.

    Correcting myself: :)
    if you use getline() to read a number, it will leave "\n" in the stream because it is not a digit.
    if you use getline() to read a string, it will read the "\n" too because it is valid for strings.

    right?
    Close, but no cigar. getline() is used for reading strings ONLY, not numbers. Also it reads input upto a specific terminator (newline by default).
    cin >> somevariable will read a value upto anything that does not match its type. Here's where it gets interesting:
    Code:
    char text[100];
    cin >> text;
    If you input "This is a test", text will only get "This" because cin will treat the space as a terminator for this input variable. If you replace cin >>text; with cin.getline(text, 100); it will read the entire line (or 100 characters, whichever comes first), since getline uses '\n' specifically as a terminator.
    When using cin to read a number, it will read upto the first non-digit character and hence it will leave the '\n' in the input stream. So your statement above should be amended to:
    if you use cin >> number to read a number, it will leave "\n" in the stream because it is not a digit.
    if you use getline() to read a string, it will read the "\n", but not assign it to the variable.
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    190
    thanks again, scorpions4ever. you remind me of the reasons why i am not using the streaming features of C++ ;)
  28. #15
  29. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Location
    Right Coast
    Posts
    25
    Rep Power
    0
    getline WILL read a number... it just "sees" it as a string.

    cin.flush() works too.

    J :)

IMN logo majestic logo threadwatch logo seochat tools logo