problem with operator overloading

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

Join Date: Mar 2006
Posts: 131
Reputation: degamer106 is an unknown quantity at this point 
Solved Threads: 0
degamer106 degamer106 is offline Offline
Junior Poster

problem with operator overloading

 
0
  #1
Feb 27th, 2007
The problem I'm having is with overloading the >> operator so that I could read data from a file directly into a class's member data. Everytime I run through the program, it just crashes. when I look through the debugger, it brings me to some page of crazy code.

So far, I've managed to make everything in my program work except just that.

I have no clue why this segment of code won't work.

  1. Atlas::Atlas(char * file)
  2. {
  3. ifstream inputFile(file);
  4. db = new Database(file);
  5.  
  6. inputFile >> *db; // gives me problems :\
  7. // db->fillDatabase();
  8. inputFile.close();
  9. }

Here's the complete code:

  1. #include <iostream>
  2. #include <cstring>
  3. #include <fstream>
  4.  
  5. #include "state.h"
  6. #include "database.h"
  7. #include "formatheader.h"
  8. #include "atlas.h"
  9.  
  10. using std::cout;
  11. using std::cin;
  12. using std::ostream;
  13.  
  14. ////////////////////////// program start ///////////////////////////////////////
  15. int main(void)
  16. {
  17. const int max = 81;
  18. char filename[max];
  19. char stateInput[max];
  20. char name[max];
  21. char cap[max];
  22. int year, popRank;
  23. int index;
  24. Atlas * pA;
  25.  
  26. //////// set up Atlas object and print its data ////////
  27. cout << "Enter filename or hit ENTER: ";
  28. cin.getline(filename, max);
  29.  
  30. if ( strlen(filename) == 0)
  31. pA = new Atlas;
  32. else
  33. pA = new Atlas(filename);
  34.  
  35. cout << *pA; // print information of all states in the database
  36.  
  37. ////// create a state to replace an existing state in the database //////
  38. cout << "Enter new information for state, comma separated: ";
  39. cin.getline(stateInput, max);
  40.  
  41. Format::parse(stateInput, name, &year, cap, &popRank); // new Format function
  42. State s(name, year, cap, popRank);
  43. cout << "This is the new information for the state: ";
  44. cout << s;
  45.  
  46. cout << "Enter index of state to be replaced: ";
  47. cin >> index;
  48. cin.ignore(100, '\n');
  49.  
  50. pA->replace(index, s);
  51. cout << *pA;
  52.  
  53. // add code you already have in lab 3 to search in the database for
  54. // the new state and print it
  55. // you should print the new state in the database, not the state s above
  56. cout << "Enter state name or press ENTER to stop: ";
  57. cin.getline(stateInput, max);
  58.  
  59. while ( stateInput[0] )
  60. {
  61. const State foundState = pA->getState( Format::fixString(stateInput) );
  62.  
  63. if ( strcmp(foundState.getName(), "none") == 0 &&
  64. strcmp(foundState.getCap(), "none") == 0 )
  65. cout << stateInput << " was not found!\n";
  66. else
  67. {
  68. cout << "State: " << Format::upperCase(foundState.getName()) << '\n';
  69. cout << "Year: " << foundState.getYear() << '\n';
  70. cout << "Capital: " << Format::upperCase(foundState.getCap()) << '\n';
  71. cout << "Population Ranking: " << foundState.getPopRank() << '\n';
  72. }
  73. cout << "\nEnter a state name or press ENTER to stop>: ";
  74. cin.getline(stateInput, max);
  75. }
  76.  
  77. cout << "Have a nice day!\n";
  78.  
  79. return 0;
  80. }
  81.  
  82. #ifndef DATABASE_H
  83. #define DATABASE_H
  84.  
  85. #include "state.h"
  86.  
  87. using std::ifstream;
  88.  
  89. class Database
  90. {
  91. public:
  92. Database(char * file = "states.txt");
  93. Database(const Database & arg);
  94. ~Database() { delete [] list; delete [] filename; }
  95. int getCount() { return count; }
  96. State * getList() { return list; }
  97. void deleteDatabase ();
  98. void fillDatabase ();
  99. friend ifstream &operator>>(ifstream &in, Database & obj);
  100. private:
  101. State * list; // array of states
  102. int count; // total count of states
  103. char * filename; // input filename
  104. };
  105.  
  106. #endif
  107.  
  108. #include <iostream>
  109. #include <cstring>
  110. #include <fstream>
  111.  
  112. #include "state.h"
  113. #include "database.h"
  114.  
  115. using std::cout;
  116. using std::cin;
  117. using std::ifstream;
  118.  
  119. ////////////////////// Database functions ////////////////////////////////
  120. // Constructor
  121. Database::Database(char * file) : count(5)
  122. {
  123. // open input file and check for open success
  124. if ( ifstream inputFile(file) )
  125. {
  126. // allocate memory for Database struct and check for success
  127. // allocate memory for filename field and initializes with filename
  128. if ( filename = new char[strlen( file ) + 1] )
  129. strcpy( filename, file );
  130. else
  131. cout << "Not enough memory!" << '\n';
  132.  
  133. // initialize list field by allocating memory for array of 10 states
  134. // and check for success
  135. if ( list = new State[5] ) {}
  136. else
  137. cout << "Not enough memory!" << '\n';
  138.  
  139. // close input file
  140. inputFile.close();
  141. }
  142. else
  143. {
  144. cout << "File not found!" << '\n';
  145. exit(0);
  146. }
  147. }
  148.  
  149. Database::Database(const Database & arg) : count(arg.count)
  150. {
  151. if ( filename = new char[strlen( arg.filename ) + 1] )
  152. strcpy( filename, arg.filename );
  153. else
  154. cout << "Not enough memory!\n";
  155.  
  156. if ( list = new State[count])
  157. for ( int cnt = 0; cnt < count; cnt++)
  158. list[cnt] = arg.list[cnt];
  159. else
  160. cout << "Not enough memory!\n";
  161. }
  162.  
  163. //fillDatabase - reads info from file and stores in array of State structs
  164. //input: pointer to Database struct
  165. //return: nothing
  166. void Database::fillDatabase ()
  167. {
  168. char name[80]; // temp variables
  169. int year;
  170. char cap[80]; // input data
  171. int popRank;
  172.  
  173. char array[100]; // temporary storage for file input
  174.  
  175. // open file from filename field of db
  176. // don't need to check for file open success because initDatabase already checked
  177. ifstream inputFile( filename );
  178.  
  179. // loop through all the states
  180. for ( int cnt = 0; cnt < count; cnt++ )
  181. {
  182. // read and parse one line of file into 4 input data fields
  183. if ( !inputFile.eof() )
  184. {
  185. inputFile.getline( array, 100 );
  186.  
  187. if ( sscanf( array, "%[^,], %d, %[^,], %d", name, &year, cap,
  188. &popRank ) == 4 )
  189. {
  190. // if tempState is created successfully from the 4 input data
  191. State tempState(name, year, cap, popRank);
  192. list[cnt] = tempState;
  193. }
  194. else
  195. {
  196. cout << "Error with file!" << '\n';
  197. return;
  198. }
  199. }
  200. }
  201.  
  202. // close file
  203. inputFile.close();
  204. }
  205.  
  206. ifstream &operator>>(ifstream &in, Database & obj)
  207. {
  208. char name[80];
  209. int year;
  210. char cap[80];
  211. int popRank;
  212.  
  213. char array[100];
  214. ifstream inputFile( in );
  215.  
  216. for (int cnt = 0; cnt < obj.count; cnt++)
  217. {
  218. if ( !inputFile.eof() )
  219. {
  220. inputFile.getline( array, 100 );
  221.  
  222. if ( sscanf( array, "%[^,], %d, %[^,], %d", name, &year, cap,
  223. &popRank ) == 4 )
  224. {
  225. State tempState(name, year, cap, popRank);
  226. obj.list[cnt] = tempState;
  227. }
  228. else
  229. cout << "Error with file!" << '\n';
  230. }
  231. }
  232.  
  233. inputFile.close();
  234.  
  235. return in;
  236. }
  237.  
  238. #ifndef STATE_H
  239. #define STATE_H
  240.  
  241. #include <iostream>
  242.  
  243. using std::ostream;
  244.  
  245. class State
  246. {
  247. public:
  248. State(char * tempName = "none", int tempYear = 0, char * tempCap = "none", int tempPopRank = 0);
  249. State( const State & arg );
  250. ~State() { delete [] name; delete [] cap; }
  251. int findState(char * stateName) const;
  252. char * getName() const { return name; }
  253. int getYear() const { return year; }
  254. char * getCap() const { return cap; }
  255. int getPopRank() const { return popRank; }
  256. void changeName(char * tempName);
  257. void changeCap(char * tempCap);
  258. void changeYear(int tempYear) { year = tempYear; }
  259. void changePopRank(int tempPopRank) { popRank = tempPopRank; }
  260. // overloaded operators
  261. friend ostream &operator<<(ostream &out, State const & obj);
  262. State & operator=(const State & tempState);
  263. private:
  264. char * name; // state name
  265. int year; // year of entry into the union
  266. char * cap; // state capital
  267. int popRank; // population ranking
  268. };
  269.  
  270. #endif
  271.  
  272. #include <iostream>
  273. #include <cstring>
  274.  
  275. #include "state.h"
  276.  
  277. using std::cout;
  278. using std::cin;
  279.  
  280. State::State(char * tempName, int tempYear, char * tempCap, int tempPopRank) : year(tempYear), popRank(tempPopRank)
  281. {
  282. char * stateName;
  283. char * capital;
  284. // if memory allocation is successful, store name
  285. if ( stateName = new char[strlen( tempName ) + 1 ] )
  286. {
  287. strcpy( stateName, tempName );
  288. name = stateName;
  289. }
  290. else
  291. cout << "Not enough memory!" << '\n';
  292.  
  293. // if memory allocation is successful, store capital
  294. if ( capital = new char[strlen( tempCap ) + 1 ] )
  295. {
  296. strcpy( capital, tempCap );
  297. cap = capital;
  298. }
  299. else
  300. cout << "Not enough memory!" << '\n';
  301. }
  302.  
  303. State::State( const State & arg ) : year(arg.year), popRank(arg.popRank)
  304. {
  305. name = new char[strlen(arg.name) + 1];
  306. strcpy(name, arg.name);
  307.  
  308. cap = new char[strlen(arg.cap) + 1];
  309. strcpy(cap, arg.cap);
  310. }
  311.  
  312. //////////////////////// State functions //////////////////////////////
  313. int State::findState(char * stateName) const
  314. {
  315. if ( strcmp( stateName, name ) == 0 )
  316. return 1;
  317. else
  318. return 0;
  319. }
  320.  
  321. void State::changeName(char * tempName)
  322. {
  323. name = new char[strlen(tempName) + 1];
  324. strcpy( name, tempName );
  325. }
  326.  
  327. void State::changeCap(char * tempCap)
  328. {
  329. cap = new char[strlen(tempCap) + 1];
  330. strcpy( cap, tempCap );
  331. }
  332.  
  333. State &State::operator=(const State & tempState)
  334. {
  335. name = new char[strlen(tempState.name) + 1];
  336. strcpy ( name, tempState.name );
  337.  
  338. year = tempState.year;
  339.  
  340. cap = new char[strlen(tempState.cap) + 1];
  341. strcpy( cap, tempState.cap );
  342.  
  343. popRank = tempState.popRank;
  344.  
  345. return *this;
  346. }
  347.  
  348. ostream &operator<<(ostream &out, State const & obj)
  349. {
  350. out << obj.name << ' ';
  351. out << obj.year << ' ';
  352. out << obj.cap << ' ';
  353. out << obj.popRank << '\n';
  354.  
  355. return out;
  356. }
  357.  
  358. #ifndef FORMAT_H
  359. #define FORMAT_H
  360.  
  361. class Format
  362. {
  363. public:
  364. static char * fixString(char * string);
  365. static char * upperCase(char * string);
  366. static void parse(char * input, char * name, int * year, char * cap, int * popRank);
  367. };
  368.  
  369. #endif
  370.  
  371. #include <iostream>
  372. #include "formatheader.h"
  373.  
  374. using std::cout;
  375.  
  376. char * Format::fixString(char * string)
  377. {
  378. // capitalize the first letter of the sentence
  379. string[0] = toupper( string[0] );
  380.  
  381. for (int cnt = 1; cnt < (strlen(string) + 1); cnt++)
  382. if ( isalpha( string[cnt] ) )
  383. string[cnt] = tolower( string[cnt] ); // set to lower case
  384. else if ( string[cnt] == ' ' )
  385. {
  386. ++cnt; // move to the beginning of the next word
  387. string[cnt] = toupper( string[cnt] ); // capitalize
  388. }
  389. return string;
  390. }
  391.  
  392. char * Format::upperCase(char * string)
  393. {
  394. for (int cnt = 0; cnt < (strlen(string) + 1); cnt++)
  395. if ( isalpha( string[cnt] ) )
  396. string[cnt] = toupper( string[cnt] );
  397. return string;
  398. }
  399.  
  400. void Format::parse(char * input, char * name, int * year, char * cap, int * popRank)
  401. {
  402. sscanf( input, "%[^,], %d, %[^,], %d", name, year, cap, popRank );
  403. }
  404.  
  405. #ifndef ATLAS_H
  406. #define ATLAS_H
  407.  
  408. #include "database.h"
  409. #include "state.h"
  410.  
  411. class Atlas
  412. {
  413. public:
  414. Atlas(char * file = "states.txt");
  415. ~Atlas() { delete db; }
  416. void replace(int index, State const & s);
  417. State getState(char * stateName) const;
  418. // overloaded operators
  419. friend ostream &operator<<(ostream &, Atlas const & obj);
  420. private:
  421. Database * db;
  422. };
  423.  
  424. #endif
  425.  
  426. #include <iostream>
  427. #include <fstream>
  428. #include "atlas.h"
  429. #include "database.h"
  430. #include "state.h"
  431.  
  432. using std::ifstream;
  433. using std::ios_base;
  434.  
  435. Atlas::Atlas(char * file)
  436. {
  437. ifstream inputFile(file);
  438. db = new Database(file);
  439.  
  440. inputFile >> *db;
  441. // db->fillDatabase();
  442. inputFile.close();
  443. }
  444.  
  445. void Atlas::replace(int index, State const & s)
  446. {
  447. State * tempState = db->getList();
  448.  
  449. delete [] tempState[index].getName();
  450. delete [] tempState[index].getCap();
  451.  
  452. tempState[index].changeName(s.getName());
  453. tempState[index].changeYear(s.getYear());
  454. tempState[index].changeCap(s.getCap());
  455. tempState[index].changePopRank(s.getPopRank());
  456. }
  457.  
  458. State Atlas::getState(char * stateName) const
  459. {
  460. State * tempState = db->getList();
  461.  
  462. for (int cnt = 0, found = 0; cnt < db->getCount() && !found; cnt++)
  463. found = tempState[cnt].findState( stateName );
  464.  
  465. if ( found )
  466. return State( tempState[cnt - 1] );
  467. else
  468. return State();
  469. }
  470.  
  471. ostream &operator<<(ostream &out, Atlas const & obj)
  472. {
  473. out << " State name Year Capital Pop. rank\n";
  474. out << "------------------------------------------------\n";
  475.  
  476. for (int cnt = 0; cnt < obj.db->getCount(); cnt++)
  477. {
  478. out.setf(ios_base::left);
  479. out.width(17);
  480. out << obj.db->getList()[cnt].getName();
  481.  
  482. out.setf(ios_base::left);
  483. out.width(8);
  484. out << obj.db->getList()[cnt].getYear();
  485.  
  486. out.setf(ios_base::left);
  487. out.width(18);
  488. out << obj.db->getList()[cnt].getCap();
  489.  
  490. out.setf(ios_base::left);
  491. out.width(2);
  492. out << obj.db->getList()[cnt].getPopRank() << '\n';
  493. }
  494.  
  495. return out;
  496. }
Reply With Quote Quick reply to this message  
Join Date: Mar 2006
Posts: 131
Reputation: degamer106 is an unknown quantity at this point 
Solved Threads: 0
degamer106 degamer106 is offline Offline
Junior Poster

Re: problem with operator overloading

 
0
  #2
Feb 27th, 2007
states.txt file

  1. Connecticut,1788,Hartford,29
  2. Maine,1820,Augusta,40
  3. Massachusetts,1788,Boston,13
  4. New Hampshire,1788,Concord,41
  5. Rhode Island,1790,Providence,43
  6. Vermont,1791,Montpelier,49
  7. Delaware,1787,Dover,45
  8. Maryland,1788,Annapolis,19
  9. New Jersey,1787,Trenton,10
  10. New York,1788,Albany,3
  11. Pennsylvania,1787,Harrisburg,6
  12. Alabama,1819,Montgomery,23
  13. Arkansas,1836,Little Rock,32
  14. Florida,1845,Tallahassee,4
  15. Georgia,1788,Atlanta,9
  16. Kentucky,1792,Frankfort,26
  17. Louisiana,1812,Baton Rouge,24
  18. Mississippi,1817,Jackson,31
  19. Missouri,1821,Jefferson City,17
  20. North Carolina,1789,Raleigh,11
  21. South Carolina,1788,Columbia,25
  22. Tennessee,1796,Nashville,16
  23. Virginia,1788,Richmond,12
  24. West Virginia,1863,Charleston,37
  25. Illinois,1818,Springfield,5
  26. Indiana,1816,Indianapolis,14
  27. Iowa,1846,Des Moines,30
  28. Kansas,1861,Topeka,33
  29. Michigan,1837,Lansing,8
  30. Minnesota,1858,St. Paul,21
  31. Nebraska,1867,Lincoln,38
  32. North Dakota,1889,Bismarck,11
  33. Ohio,1803,Columbus,7
  34. South Dakota,1889,Pierre,46
  35. Wisconsin,1848,Madison,20
  36. Arizona,1912,Phoenix,18
  37. New Mexico,1912,Santa Fe,36
  38. Oklahoma,1907,Oklahoma City,28
  39. Texas,1845,Austin,2
  40. Alaska,1959,Juneau,47
  41. California,1850,Sacramento,1
  42. Colorado,1867,Denver,22
  43. Hawaii,1959,Honolulu,42
  44. Idaho,1890,Boise,39
  45. Montana,1889,Helena,44
  46. Nevada,1864,Carson City,35
  47. Oregon,1859,Salem,27
  48. Utah,1896,Salt Lake City,34
  49. Washington,1889,Olympia,15
  50. Wyoming,1890,Cheyenne,50
Reply With Quote Quick reply to this message  
Join Date: Mar 2006
Posts: 131
Reputation: degamer106 is an unknown quantity at this point 
Solved Threads: 0
degamer106 degamer106 is offline Offline
Junior Poster

Re: problem with operator overloading

 
0
  #3
Feb 27th, 2007
ok i figured the problem out. It turns out that I opened the same file twice..
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