overloaded input stream help

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Feb 2007
Posts: 3
Reputation: oolatin79 is an unknown quantity at this point 
Solved Threads: 0
oolatin79 oolatin79 is offline Offline
Newbie Poster

overloaded input stream help

 
0
  #1
Feb 13th, 2007
Hi guys/gals, I'm having a problem with a function that overloads the input stream. The problem is that the getline crashes on the second iteration of the while loop:

  1. //overloaded input operator
  2. istream& operator>>(istream& is, vector<EmailHeader>& ehVec)
  3. {
  4.  
  5. EmailHeader headerInput;
  6. cout << "Enter an email Header: Ctrl-D to quit" << endl;
  7. while(getline(is, headerInput.to))
  8. {
  9. getline(is, headerInput.from);
  10.  
  11. // crash occurs after the user hits enter (second iteration)
  12. getline(is, headerInput.subject);
  13.  
  14. is >> headerInput.Date.month;
  15. is >> headerInput.Date.day;
  16. is >> headerInput.Date.year;
  17.  
  18. ehVec.push_back(headerInput);
  19. cout << "Enter another email Header: Ctrl-D to quit" << endl;
  20. }
  21. return is;
  22. }
EmailHeader is a simple test class which holds string members for "From", "To", "Subject" fields and integer values for the dates.

I'm calling the overloaded input function from my main:

  1. int main()
  2. {
  3. vector<EmailHeader> emVec;
  4.  
  5. cin >> emVec;
  6.  
  7. //other code
  8. }
Any help and suggestions would be greatly appreciated. TIA.
Last edited by oolatin79; Feb 13th, 2007 at 10:11 pm.
Reply With Quote Quick reply to this message  
Join Date: Apr 2006
Posts: 5,050
Reputation: John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold 
Solved Threads: 332
Team Colleague
John A's Avatar
John A John A is offline Offline
Vampirical Lurker

Re: overloaded input stream help

 
0
  #2
Feb 13th, 2007
I'm not entirely sure what the problem is, but something doesn't good in your code when you're mixing the getline() statements and in >> operators...

You see, when you use istream >> a_variable, it always leaves a trailing newline in the input stream. Then when you try to use getline(), you end up with a newline character instead of the input you expected to get.

The best solution would be to simply use all getline() statements instead of mixing them, however if you don't want to, you can simply clear the input buffer like this:
  1. cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Last edited by John A; Feb 13th, 2007 at 10:29 pm.
"Technological progress is like an axe in the hands of a pathological criminal."
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 3
Reputation: oolatin79 is an unknown quantity at this point 
Solved Threads: 0
oolatin79 oolatin79 is offline Offline
Newbie Poster

Re: overloaded input stream help

 
0
  #3
Feb 13th, 2007
Hi JoeProgrammer, thanks for the prompt response. I basically wanted to read in 3 strings(with spaces) and 3 ints.

The getline() allows me to input a string with spaces where as the >> cuts it off before the first space character.

So I figured that I'd have to mix in order to get the desired results.

I didn't know the is >> variable always left a trailing newline though.

Thanks for your help. I'll try clearing out the input buffer.

Do you know of a better method of reading in the strings with spaces and ints?
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,335
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1454
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is online now Online
Still Learning

Re: overloaded input stream help

 
0
  #4
Feb 13th, 2007
This works, its essentially the same you had though. I added code to flush the keyboard buffer after each integer input. That may have been your problem.

  1. #include <string>
  2. #include <vector>
  3. #include <iostream>
  4. using namespace std;
  5.  
  6. class dt
  7. {
  8. public:
  9. int month,day,year;
  10. dt() {month = day = year = 0;}
  11. };
  12.  
  13. class EmailHeader
  14. {
  15. public:
  16. string to;
  17. string from;
  18. string subject;
  19. dt Date;
  20. };
  21.  
  22. //overloaded input operator
  23. istream& operator>>(istream& is, vector<EmailHeader>& ehVec)
  24. {
  25. EmailHeader headerInput;
  26. cout << "Enter an email Header: Ctrl-Z to quit" << endl;
  27. while(getline(is,headerInput.to))
  28. {
  29. getline(is, headerInput.from);
  30. getline(is, headerInput.subject); //crash occurs here on second iteration after the
  31. cout << "month: "; // user hits the return key, so input below is skipped
  32. is >> headerInput.Date.month;
  33. is.ignore();
  34. cout << "day: ";
  35. is >> headerInput.Date.day;
  36. is.ignore();
  37. cout << "Year: ";
  38. is >> headerInput.Date.year;
  39. is.ignore();
  40.  
  41. ehVec.push_back(headerInput);
  42. cout << "Enter another email Header: Ctrl-Z to quit" << endl;
  43. }
  44. return is;
  45. }
  46.  
  47. int main()
  48. {
  49. vector<EmailHeader> emVec;
  50.  
  51. cin >> emVec;
  52.  
  53. //other code
  54. return 0;
  55. }
Last edited by Ancient Dragon; Feb 13th, 2007 at 10:48 pm.
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
Reply With Quote Quick reply to this message  
Join Date: Apr 2006
Posts: 5,050
Reputation: John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold 
Solved Threads: 332
Team Colleague
John A's Avatar
John A John A is offline Offline
Vampirical Lurker

Re: overloaded input stream help

 
0
  #5
Feb 13th, 2007
Originally Posted by oolatin79 View Post
The getline() allows me to input a string with spaces where as the >> cuts it off before the first space character.
Well, yes I realized that. But many newbies don't realize the hidden gotchas of mixing functions which grab entire lines, such as fgets() and getline() with functions which simply scan for what they need, like cin >> and scanf().

cin >> works fine on its own, because although it leaves a trailing newline in the input buffer, it removes it when it reads next. So you can imagine this works perfectly until you use a function which reads until the first newline. Then you have problems.

The best thing to do is to only use cin >> when you know what you're doing (even though tons of online tutorials use it), so for most newbies it would in fact be much safer practice to only use getline() for grabbing their input.

Do you know of a better method of reading in the strings with spaces and ints?
The best method is to read in everything with getline(), and then parse out what you need from that. Although it sounds more complex, it's quite safe. And it's less complex if you pop that result into a string stream, which you can then safely use the >> operator without worrying about newlines.
"Technological progress is like an axe in the hands of a pathological criminal."
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 3
Reputation: oolatin79 is an unknown quantity at this point 
Solved Threads: 0
oolatin79 oolatin79 is offline Offline
Newbie Poster

Re: overloaded input stream help

 
0
  #6
Feb 13th, 2007
JoeProgrammer: Thanks again for your suggestion and knowledge.

The initial method you'd posted that clears the input buffer did the trick:

  1. char ch;
  2. while((ch=is.get()) != '\n' && ch != EOF);
For some reason, the other method you suggested didn't work though:

  1. cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
AncientDragon: thanks for your response as well. I tried using your method and it didn't work properly using GCC. It did work using DevC++(mingw compiler I beleive), so I'm not really sure why this happened, I can only attribute the erratic behavior to the different compilers.

-edit-

actually if I only use one "is.ignore()" then it does work using gcc. Thanks again!
Last edited by oolatin79; Feb 13th, 2007 at 11:22 pm.
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,335
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1454
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is online now Online
Still Learning

Re: overloaded input stream help

 
0
  #7
Feb 13th, 2007
I used VC++ 2005 Express to test your code.
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC