| | |
cin.ignore() ??????
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
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.
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):
c++ Syntax (Toggle Plain Text)
#include <string> #include <iostream> using namespace std ; class Person { public: Person ( ) ; Person ( string theName ) ; Person ( const Person & theObject ) ; string getName ( ) const ; Person operator =( const Person & rtSide ) ; friend istream & operator >>( istream & is , Person & p ) ; friend ostream & operator <<( ostream & os , const Person & p ) ; private: string name ; } ; #include "person.h" Person::Person ( ) : name ( "John Doe" ) { } Person::Person ( string theName ) : name ( theName ) { } Person::Person ( const Person & theObject ) { name = theObject.name ; } Person Person::operator =( const Person & rtSide ) { //useless here if ( name == rtSide.name ) return *this ; name = rtSide.name ; return *this ; } istream & operator >>( istream & is , Person & p ) { cout << "Name: " << flush ; getline ( is , p.name ) ; return is ; } ostream & operator <<( ostream & os , const Person & p ) { os << "Name: " << p.name << endl ; return os ; } string Person::getName ( ) const { return name ; } #include <string> #include <iostream> using namespace std ; class Vehicle { public: Vehicle ( ) ; Vehicle ( string newManufacturer , int newCylinders , Person newOwner ) ; Vehicle ( const Vehicle & theObject ) ; Vehicle operator =( const Vehicle & rtSide ) ; friend istream & operator >>( istream & is , Vehicle & v ) ; friend ostream & operator <<( ostream & os , const Vehicle & v ) ; protected: string manufacturer ; int cylinders ; Person owner ; } ; class Truck : public Vehicle { public: Truck ( ) ; Truck( string manf , int cyl , Person newO , double newLoad, int newTowCap, int maxPas, bool kingCab ) ; Truck operator =( const Truck & rtSide ) ; friend istream & operator >>( istream & is , Truck & t ) ; friend ostream & operator <<( ostream & os , const Truck & t ) ; void setOwner ( ) ; private: double loadCap ; int towingCap ; int maxPassengers ; bool kingCab ; } ; #include "person.h" #include "vehicle.h" Vehicle::Vehicle ( ) : manufacturer ( "No manufacturer set" ) , cylinders ( 0 ) , owner ( Person ( ) ) { } Vehicle::Vehicle ( string newManufacturer , int newCylinders , Person newOwner ) : manufacturer ( newManufacturer ) , cylinders ( newCylinders ) , owner ( newOwner ) { } Vehicle::Vehicle ( const Vehicle & theObject ) { manufacturer = theObject.manufacturer ; cylinders = theObject.cylinders ; owner = theObject.owner ; } Vehicle Vehicle::operator =( const Vehicle & rtSide ) { //check for self assignment not necessary without the use of pointers or arrays. manufacturer = rtSide.manufacturer ; cylinders = rtSide.cylinders ; owner = rtSide.owner ; return *this ; } istream & operator >>( istream & is , Vehicle & v ) { cout << "Manufacturer: " << flush ; is >> v.manufacturer ; cout << "Number of cylinders: " << flush ; is >> v.cylinders ; cout << "Owner: " << flush ; is >> v.owner ; return is ; } ostream & operator <<( ostream & os , const Vehicle & v ) { os << "Manufacturer: " << v.manufacturer << endl ; os << "Number of cylinders: " << v.cylinders << endl ; os << "Owner: " << v.owner << endl ; return os ; } Truck::Truck ( ) : Vehicle ( ) , loadCap ( 0.0 ) , towingCap ( 0 ) , maxPassengers ( 0 ) , kingCab ( false ) { } 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 ) { } Truck Truck::operator = ( const Truck & rtSide ) { //check for self assignment not necessary without the use of pointers or arrays. Vehicle::operator = ( rtSide ) ; loadCap = rtSide.loadCap ; towingCap = rtSide.towingCap ; maxPassengers = rtSide.maxPassengers ; kingCab = rtSide.kingCab ; return *this ; } istream & operator >>( istream & is , Truck & t ) { if ( t.manufacturer == "No manufacturer set" ) { cout << "Manufacturer: " << flush ; is >> t.manufacturer ; is.ignore ( ) ; cout << "Number of cylinders: " << flush ; cout << flush ; cout << "Owner: " << flush ; is >> t.owner ; } char xCab ; cout << "Load Capacity (tons): " << flush ; is >> t.loadCap ; cout << "Towing Capacity (lbs): " << flush ; is >> t.towingCap ; cout << "Maximum Passengers: " << flush ; is >> t.maxPassengers ; cout << "King Cab? (y/n): " << flush ; is >> xCab ; if ( xCab == 'y' || xCab == 'Y' ) t.kingCab = true ; else t.kingCab = false ; return is ; } ostream & operator <<( ostream & os , const Truck & t ) { os << "Owner: " << t.owner.getName ( ) << endl ; os << "Manufacturer: " << t.manufacturer << endl ; os << "Number of cylinders: " << t.cylinders << endl ; os << "Load Capacity (tons): " << t.loadCap << endl ; os << "Towing Capacity (lbs): " << t.towingCap << endl ; os << "Maximum Passengers: " << t.maxPassengers << endl ; os << "King Cab: " ; if ( t.kingCab == true ) os << "Yes" << endl ; else os << "No" << endl ; return os ; } void Truck::setOwner ( ) { cout << "New Owner: " << flush ; cin >> owner ; cout << "Owner changed to " << owner << ".\n" ; } #include "person.h" #include "vehicle.h" int main ( ) { Person caleb ; Person todd ( "Todd Jones" ) ; cin >> caleb ; Truck silverado ; Truck titan ( "Nissan" , 8 , caleb , 2.3 , 7200 , 6 , true ) ; cin >> silverado ; cout << endl ; cout << silverado ; cout << titan ; Truck prototype ( silverado ) ; prototype.setOwner ( ) ; cout << prototype ; return 0 ; }
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
-Edsger Dijkstra
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.
Whew. Get some sleep.
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.
you should try flushing the buffer too... it should improve your program's processing...
like this:
or with endl; :
which may substitute
like this:
c Syntax (Toggle Plain Text)
cout<<"/*whatever you want*/"<<flush;
c Syntax (Toggle Plain Text)
cout<<"/*Whatever you want*/"<<endl;
\n Last edited by Nichito; Nov 1st, 2007 at 4:27 am.
-->sometimes i wanna take my toaster in a bath<-- •
•
•
•
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.
C++ Syntax (Toggle Plain Text)
string Truck::getManf ( ) { string manf ; cout << "Manufacturer: " << flush ; cin >> manf ; return manf ; } istream & operator >>( istream & is , Vehicle & v ) { is >> getManf ; return is ; }
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
-Edsger Dijkstra
•
•
•
•
Not sure I understand. If I use getTruckInfo(), there will be no point for overloading the istream, correct?
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.
Alright, that all makes sense. Thanks.
Question though: When do you overload the istream?
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
-Edsger Dijkstra
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:
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:
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.
So, for example, if you have a class named Employee:
C++ Syntax (Toggle Plain Text)
class Person { string surname; string given_name; string job_title; time_t hire_date; float pay_rate; //etc };
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:
C++ Syntax (Toggle Plain Text)
Shunpike Stan Knight Bus Conductor 1993/4/12 $7.15 Bones Amelia Susan Head of the Department of Magical Law Enforcement 1972/5/19 $50.32
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.
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
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.
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
-Edsger Dijkstra
![]() |
Similar Threads
- cin.get() & cin.ignore()?! (C++)
- cin.get issue (C++)
- blood sheds cin.get (confusing) (C++)
Other Threads in the C++ Forum
- Previous Thread: Program does not recognize actual input = expected output
- Next Thread: Passing a character array to ifstream
| Thread Tools | Search this Thread |
api array arrays based beginner binary bitmap c++ c/c++ calculator char char* class classes code coding compile compiler console conversion convert count data database delete deploy developer dll download dynamiccharacterarray email encryption error file forms fstream function functions game generator getline givemetehcodez graph homeworkhelp homeworkhelper iamthwee ifstream input int integer java lib list loop looping loops map math matrix memory multiple news node number numbertoword output parameter pointer problem program programming project proxy python random read recursion recursive reference rpg sorting string strings struct temperature template text tree url variable vector video visual visualstudio win32 windows winsock word wordfrequency wxwidgets






