cin.ignore() ??????

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

Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

cin.ignore() ??????

 
0
  #1
Nov 1st, 2007
Ok, I'm going post all of my code, and hopefully someone can tell me where my error is at. I'm guessing I need to do a cin.ignore() somewhere, but I'm not sure where. I've tried it in a couple of places, but nothing has fixed the problem completely.

  1. #include <string>
  2. #include <iostream>
  3. using namespace std ;
  4.  
  5. class Person
  6. {
  7. public:
  8. Person ( ) ;
  9. Person ( string theName ) ;
  10. Person ( const Person & theObject ) ;
  11.  
  12. string getName ( ) const ;
  13. Person operator =( const Person & rtSide ) ;
  14. friend istream & operator >>( istream & is , Person & p ) ;
  15. friend ostream & operator <<( ostream & os , const Person & p ) ;
  16. private:
  17. string name ;
  18. } ;
  19.  
  20.  
  21.  
  22. #include "person.h"
  23.  
  24. Person::Person ( ) : name ( "John Doe" )
  25. { }
  26.  
  27. Person::Person ( string theName ) : name ( theName )
  28. { }
  29.  
  30. Person::Person ( const Person & theObject )
  31. {
  32. name = theObject.name ;
  33. }
  34.  
  35. Person Person::operator =( const Person & rtSide )
  36. {
  37. //useless here
  38. if ( name == rtSide.name )
  39. return *this ;
  40.  
  41. name = rtSide.name ;
  42. return *this ;
  43. }
  44.  
  45. istream & operator >>( istream & is , Person & p )
  46. {
  47. cout << "Name: " << flush ;
  48. getline ( is , p.name ) ;
  49.  
  50. return is ;
  51. }
  52.  
  53. ostream & operator <<( ostream & os , const Person & p )
  54. {
  55. os << "Name: " << p.name << endl ;
  56.  
  57. return os ;
  58. }
  59.  
  60. string Person::getName ( ) const
  61. {
  62. return name ;
  63. }
  64.  
  65.  
  66.  
  67. #include <string>
  68. #include <iostream>
  69. using namespace std ;
  70.  
  71. class Vehicle
  72. {
  73. public:
  74. Vehicle ( ) ;
  75. Vehicle ( string newManufacturer , int newCylinders , Person newOwner ) ;
  76. Vehicle ( const Vehicle & theObject ) ;
  77.  
  78. Vehicle operator =( const Vehicle & rtSide ) ;
  79. friend istream & operator >>( istream & is , Vehicle & v ) ;
  80. friend ostream & operator <<( ostream & os , const Vehicle & v ) ;
  81. protected:
  82. string manufacturer ;
  83. int cylinders ;
  84. Person owner ;
  85. } ;
  86.  
  87. class Truck : public Vehicle
  88. {
  89. public:
  90. Truck ( ) ;
  91. Truck( string manf , int cyl , Person newO , double newLoad, int newTowCap, int maxPas, bool kingCab ) ;
  92.  
  93. Truck operator =( const Truck & rtSide ) ;
  94. friend istream & operator >>( istream & is , Truck & t ) ;
  95. friend ostream & operator <<( ostream & os , const Truck & t ) ;
  96.  
  97. void setOwner ( ) ;
  98. private:
  99. double loadCap ;
  100. int towingCap ;
  101. int maxPassengers ;
  102. bool kingCab ;
  103. } ;
  104.  
  105.  
  106.  
  107. #include "person.h"
  108. #include "vehicle.h"
  109.  
  110. Vehicle::Vehicle ( ) : manufacturer ( "No manufacturer set" ) , cylinders ( 0 ) , owner ( Person ( ) )
  111. { }
  112.  
  113. Vehicle::Vehicle ( string newManufacturer , int newCylinders , Person newOwner ) : manufacturer ( newManufacturer ) , cylinders ( newCylinders ) , owner ( newOwner )
  114. { }
  115.  
  116. Vehicle::Vehicle ( const Vehicle & theObject )
  117. {
  118. manufacturer = theObject.manufacturer ;
  119. cylinders = theObject.cylinders ;
  120. owner = theObject.owner ;
  121. }
  122.  
  123. Vehicle Vehicle::operator =( const Vehicle & rtSide )
  124. {
  125. //check for self assignment not necessary without the use of pointers or arrays.
  126.  
  127. manufacturer = rtSide.manufacturer ;
  128. cylinders = rtSide.cylinders ;
  129. owner = rtSide.owner ;
  130. return *this ;
  131. }
  132.  
  133. istream & operator >>( istream & is , Vehicle & v )
  134. {
  135. cout << "Manufacturer: " << flush ;
  136. is >> v.manufacturer ;
  137. cout << "Number of cylinders: " << flush ;
  138. is >> v.cylinders ;
  139. cout << "Owner: " << flush ;
  140. is >> v.owner ;
  141.  
  142. return is ;
  143. }
  144.  
  145. ostream & operator <<( ostream & os , const Vehicle & v )
  146. {
  147. os << "Manufacturer: " << v.manufacturer << endl ;
  148. os << "Number of cylinders: " << v.cylinders << endl ;
  149. os << "Owner: " << v.owner << endl ;
  150.  
  151. return os ;
  152. }
  153.  
  154. Truck::Truck ( ) : Vehicle ( ) , loadCap ( 0.0 ) , towingCap ( 0 ) , maxPassengers ( 0 ) , kingCab ( false )
  155. { }
  156.  
  157. Truck::Truck( string manf , int cyl , Person newO , double newLoad, int newTowCap, int maxPas, bool kingCab ) : Vehicle ( manf , cyl , newO ) , loadCap ( newLoad ) , towingCap ( newTowCap ) , maxPassengers ( maxPas ) , kingCab ( kingCab )
  158. { }
  159.  
  160. Truck Truck::operator = ( const Truck & rtSide )
  161. {
  162. //check for self assignment not necessary without the use of pointers or arrays.
  163.  
  164. Vehicle::operator = ( rtSide ) ;
  165. loadCap = rtSide.loadCap ;
  166. towingCap = rtSide.towingCap ;
  167. maxPassengers = rtSide.maxPassengers ;
  168. kingCab = rtSide.kingCab ;
  169.  
  170. return *this ;
  171. }
  172.  
  173. istream & operator >>( istream & is , Truck & t )
  174. {
  175. if ( t.manufacturer == "No manufacturer set" )
  176. {
  177. cout << "Manufacturer: " << flush ;
  178. is >> t.manufacturer ;
  179. is.ignore ( ) ;
  180. cout << "Number of cylinders: " << flush ;
  181. cout << flush ;
  182. cout << "Owner: " << flush ;
  183. is >> t.owner ;
  184. }
  185.  
  186. char xCab ;
  187. cout << "Load Capacity (tons): " << flush ;
  188. is >> t.loadCap ;
  189. cout << "Towing Capacity (lbs): " << flush ;
  190. is >> t.towingCap ;
  191. cout << "Maximum Passengers: " << flush ;
  192. is >> t.maxPassengers ;
  193. cout << "King Cab? (y/n): " << flush ;
  194. is >> xCab ;
  195. if ( xCab == 'y' || xCab == 'Y' )
  196. t.kingCab = true ;
  197. else
  198. t.kingCab = false ;
  199.  
  200. return is ;
  201. }
  202.  
  203. ostream & operator <<( ostream & os , const Truck & t )
  204. {
  205. os << "Owner: " << t.owner.getName ( ) << endl ;
  206. os << "Manufacturer: " << t.manufacturer << endl ;
  207. os << "Number of cylinders: " << t.cylinders << endl ;
  208. os << "Load Capacity (tons): " << t.loadCap << endl ;
  209. os << "Towing Capacity (lbs): " << t.towingCap << endl ;
  210. os << "Maximum Passengers: " << t.maxPassengers << endl ;
  211. os << "King Cab: " ;
  212. if ( t.kingCab == true )
  213. os << "Yes" << endl ;
  214. else
  215. os << "No" << endl ;
  216.  
  217. return os ;
  218. }
  219.  
  220. void Truck::setOwner ( )
  221. {
  222. cout << "New Owner: " << flush ;
  223. cin >> owner ;
  224.  
  225. cout << "Owner changed to " << owner << ".\n" ;
  226. }
  227.  
  228.  
  229.  
  230.  
  231. #include "person.h"
  232. #include "vehicle.h"
  233.  
  234. int main ( )
  235. {
  236. Person caleb ;
  237. Person todd ( "Todd Jones" ) ;
  238.  
  239. cin >> caleb ;
  240.  
  241. Truck silverado ;
  242. Truck titan ( "Nissan" , 8 , caleb , 2.3 , 7200 , 6 , true ) ;
  243.  
  244. cin >> silverado ;
  245.  
  246. cout << endl ;
  247. cout << silverado ;
  248. cout << titan ;
  249.  
  250. Truck prototype ( silverado ) ;
  251. prototype.setOwner ( ) ;
  252. cout << prototype ;
  253.  
  254. return 0 ;
  255. }
Sample output:

Name: Caleb
Manufacturer: Chevy
Number of cylinders: Owner: Name:


Another sample (without the cin.ignore() at line 179):

Name: Caleb
Manufacturer: Chevy
Number of cylinders: Owner: Name: Load Capacity (tons):


Last edited by Duki; Nov 1st, 2007 at 1:48 am.
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 1,952
Reputation: Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of 
Solved Threads: 214
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: cin.ignore() ??????

 
0
  #2
Nov 1st, 2007
Your errors are not invincible, but they are all due to a very bad mixture of I/O (sorry).

You'll need to trace your program (using a piece of paper and pencil) to see what is happening.

Firstly, don't use output methods (cout, etc.) inside an overloaded input operator (>>). That is just bad design no matter how you look at it. Yes, I know it can be done, but it breaks every model there is, and will lead to future failures. Use instead a named method like getTruckInfoFromUser() or somesuch if you plan to use both input and output methods together. Don't disguise them both under the pretense of only one.

The mixup with "Number of cylinders: Owner: Name:" has to do with your use of these overloads. (After number of cylinders you never use <<. You cout "Owner:" then send off to Person's overloaded >> which couts "Name:". And you use a mixture of getline() and >> and ignore(). While not necessarily a problem, pick one --preferably only the one matching your operator.)

I hope you don't feel I've been unnecessarily harsh... but this really is industrial strength advice, and if you fail to heed it it really will bite you, and hard, later. Change your operators to named functions; only then mix and match input and output as you please. If you use getline() to get strings you won't need to use ignore() and you will avoid user input errors that can mess-up your data stream.

P.S. If your professor has asked the class to do this weird I/O stuff with the input operators, you need to go to your headmaster and get your professor fired. I'm serious.

Good luck.

[EDIT]
Oh yeah, almost forgot...

Always test for self assignment. Don't test against internal fields (two different objects can have the same values in the same fields). Test against the object itself.
if (theObject == *this) return *this;

Whew. Get some sleep.
Last edited by Duoas; Nov 1st, 2007 at 3:03 am.
Reply With Quote Quick reply to this message  
Join Date: Mar 2007
Posts: 1,429
Reputation: Nichito is an unknown quantity at this point 
Solved Threads: 30
Featured Poster
Nichito's Avatar
Nichito Nichito is offline Offline
Nearly a Posting Virtuoso

Re: cin.ignore() ??????

 
0
  #3
Nov 1st, 2007
you should try flushing the buffer too... it should improve your program's processing...

like this:

  1. cout<<"/*whatever you want*/"<<flush;
or with endl; :

  1. cout<<"/*Whatever you want*/"<<endl;
which may substitute \n
Last edited by Nichito; Nov 1st, 2007 at 4:27 am.
-->sometimes i wanna take my toaster in a bath<--
Reply With Quote Quick reply to this message  
Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

Re: cin.ignore() ??????

 
0
  #4
Nov 1st, 2007
Originally Posted by duoas
Firstly, don't use output methods (cout, etc.) inside an overloaded input operator (>>). That is just bad design no matter how you look at it. Yes, I know it can be done, but it breaks every model there is, and will lead to future failures. Use instead a named method like getTruckInfoFromUser() or somesuch if you plan to use both input and output methods together. Don't disguise them both under the pretense of only one.
Not sure I understand. If I use getTruckInfo(), there will be no point for overloading the istream, correct? Or could I do something along the lines of
  1. string Truck::getManf ( )
  2. {
  3. string manf ;
  4.  
  5. cout << "Manufacturer: " << flush ;
  6. cin >> manf ;
  7. return manf ;
  8. }
  9.  
  10. istream & operator >>( istream & is , Vehicle & v )
  11. {
  12. is >> getManf ;
  13. return is ;
  14. }
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 1,952
Reputation: Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of 
Solved Threads: 214
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: cin.ignore() ??????

 
0
  #5
Nov 1st, 2007
Not sure I understand. If I use getTruckInfo(), there will be no point for overloading the istream, correct?
Exactly. The >> operator is for doing input, nothing else. Google "C++ serialization" for more information.

When you overload any operator to do something different than its primary function (or, in this case, something directly opposite its primary function) you are asking for trouble. Its like overloading ++ to do some power series expansion or some such. Just don't do it. You are always better off creating a method with a name that explains what it does.

You may say, "well, I know what I am doing" or "I'm the only one using the class" or "It's just some dumb homework" or something like that... but computer models only work when followed. Even in this short example you made an error as a direct consequence of breaking the mold: "Owner: Name:". Had you not overloaded Person's >> to do something weird, your code would have worked as expected.

I am not too fond of school environments that let people get away with such stuff because it has the same corrosive influence on the student's programming ability as the spaghetti code that BASIC encouraged.

Hope that makes sense.

[EDIT]
Oh yeah, there is no need to write a method for every field in the object. Just do what you were trying to do in the >> operator: ask for each piece of information in turn and return once the entire object has been initialized.
Last edited by Duoas; Nov 1st, 2007 at 5:45 pm.
Reply With Quote Quick reply to this message  
Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

Re: cin.ignore() ??????

 
0
  #6
Nov 2nd, 2007
Alright, that all makes sense. Thanks.
Question though: When do you overload the istream?
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
Reply With Quote Quick reply to this message  
Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

Re: cin.ignore() ??????

 
1
  #7
Nov 3rd, 2007
bump
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 1,952
Reputation: Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of 
Solved Threads: 214
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: cin.ignore() ??????

 
1
  #8
Nov 3rd, 2007
You overload the istream whenever you want to do serial input. This requires your class to have a definite (and hopefully unique) way to store its data. You can format it any way you desire, so long as you can tell where it begins and ends.

So, for example, if you have a class named Employee:
  1. class Person {
  2. string surname;
  3. string given_name;
  4. string job_title;
  5. time_t hire_date;
  6. float pay_rate;
  7. //etc
  8. };

You can pick all kinds of ways to save this information. One would be just to list each piece as a string in a text file:
  1. Shunpike
  2. Stan
  3. Knight Bus Conductor
  4. 1993/4/12
  5. $7.15
  6.  
  7. Bones
  8. Amelia Susan
  9. Head of the Department of Magical Law Enforcement
  10. 1972/5/19
  11. $50.32
Given a file like this and an appropriately coded >> operator you could read in the data, knowing that there are five lines of data plus one blank line per record. No need to ask questions or do anything else.

It depends entirely on your storage requirements. In this example I chose a simple line-by-line data dump. It can be more carefully organized textual information (for instance, if your Employee data is mixed with other types of data), or purely binary. It is up to you.

However, you really should read up on serialization.

Hope this helps.
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 7,329
Reputation: christina>you is on a distinguished road 
Solved Threads: 4
Featured Poster
christina>you's Avatar
christina>you christina>you is offline Offline
Posting Sage

Re: cin.ignore() ??????

 
2
  #9
Nov 4th, 2007
edit] didn't mean to post. Sorry.
Last edited by christina>you; Nov 4th, 2007 at 1:10 am.
I am nothing special; of this I am sure. I am a common man with common thoughts, and I’ve led a common life. There are no monuments dedicated to me and my name will soon be forgotten, but I’ve loved another with all my heart and soul, and to me, this has always been enough. -The Notebook
Reply With Quote Quick reply to this message  
Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

Re: cin.ignore() ??????

 
0
  #10
Nov 4th, 2007
Thanks a ton. Your explanations are really helping me to grasp the concepts.

Also, on the other two problems you were helping me with, they're fixed now. Thanks a bunch.

It helped a lot. As always.
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
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