C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
1200+ fellow developers rate and compare features of the top IDEs, like Visual Studio, Eclipse, RAD, Delphi and others, across 13 categories. Enjoy this FREE Download of the IDE User Satisfaction Study by Evans Data Corporation. Download Now!
  #1  
Old February 20th, 2003, 01:55 AM
7stud 7stud is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Feb 2001
Posts: 1,327 7stud User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 4 h 44 m 50 sec
Reputation Power: 9
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.

Reply With Quote
  #2  
Old February 20th, 2003, 12:56 PM
M.Hirsch M.Hirsch is offline
Contributing User
Dev Shed God 1st Plane (5500 - 5999 posts)
 
Join Date: Oct 2000
Location: Back in the real world.
Posts: 5,969 M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Month 1 Day 22 h 39 m 55 sec
Reputation Power: 184
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.... http://forums.devshed.com/showthread.php?threadid=51971
[/edit]
__________________
--
Manuel Hirsch - Linux, FreeBSD, programming, administration articles, tutorials and more.

Last edited by M.Hirsch : February 20th, 2003 at 01:41 PM.

Reply With Quote
  #3  
Old February 20th, 2003, 01:31 PM
7stud 7stud is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Feb 2001
Posts: 1,327 7stud User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 4 h 44 m 50 sec
Reputation Power: 9
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.

Reply With Quote
  #4  
Old February 20th, 2003, 01:37 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is online now
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,436 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 4 Weeks 1 Day 23 h 39 m 12 sec
Reputation Power: 784
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!

Reply With Quote
  #5  
Old February 20th, 2003, 01:40 PM
M.Hirsch M.Hirsch is offline
Contributing User
Dev Shed God 1st Plane (5500 - 5999 posts)
 
Join Date: Oct 2000
Location: Back in the real world.
Posts: 5,969 M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Month 1 Day 22 h 39 m 55 sec
Reputation Power: 184
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

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.

Reply With Quote
  #6  
Old February 20th, 2003, 01:55 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is online now
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,436 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 4 Weeks 1 Day 23 h 39 m 12 sec
Reputation Power: 784
>> 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

Reply With Quote
  #7  
Old February 20th, 2003, 02:00 PM
M.Hirsch M.Hirsch is offline
Contributing User
Dev Shed God 1st Plane (5500 - 5999 posts)
 
Join Date: Oct 2000
Location: Back in the real world.
Posts: 5,969 M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Month 1 Day 22 h 39 m 55 sec
Reputation Power: 184
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)


Reply With Quote
  #8  
Old February 20th, 2003, 02:09 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is online now
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,436 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 4 Weeks 1 Day 23 h 39 m 12 sec
Reputation Power: 784
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.

Reply With Quote
  #9  
Old February 20th, 2003, 02:15 PM
M.Hirsch M.Hirsch is offline
Contributing User
Dev Shed God 1st Plane (5500 - 5999 posts)
 
Join Date: Oct 2000
Location: Back in the real world.
Posts: 5,969 M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Month 1 Day 22 h 39 m 55 sec
Reputation Power: 184
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?

Reply With Quote
  #10  
Old February 20th, 2003, 02:23 PM
7stud 7stud is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Feb 2001
Posts: 1,327 7stud User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 4 h 44 m 50 sec
Reputation Power: 9
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/~tgibs...ial/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.

Reply With Quote
  #11  
Old February 20th, 2003, 02:31 PM
M.Hirsch M.Hirsch is offline
Contributing User
Dev Shed God 1st Plane (5500 - 5999 posts)
 
Join Date: Oct 2000
Location: Back in the real world.
Posts: 5,969 M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Month 1 Day 22 h 39 m 55 sec
Reputation Power: 184
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?

Reply With Quote
  #12  
Old February 20th, 2003, 02:37 PM
7stud 7stud is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Feb 2001
Posts: 1,327 7stud User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 4 h 44 m 50 sec
Reputation Power: 9
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.

Reply With Quote
  #13  
Old February 20th, 2003, 04:02 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is online now
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,436 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 4 Weeks 1 Day 23 h 39 m 12 sec
Reputation Power: 784
Quote:
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.

Reply With Quote