944,196 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 4649
  • C++ RSS
You are currently viewing page 1 of this multi-page discussion thread
May 4th, 2007
0

Custom Class - File I/O

Expand Post »
I've got a custom class that is as follows:
C++ Syntax (Toggle Plain Text)
  1. class course {
  2. private:
  3. string prefix;
  4. int number;
  5. string title;
  6. int credits;
  7. char grade;
  8. public:
  9. //Constructors
  10. course();
  11. course(string, int, string, int, char);
  12. //Accessors
  13. void set();
  14. void print() const;
  15. string get_prefix() const;
  16. int get_number() const;
  17. string get_title() const;
  18. int get_credits() const;
  19. char get_grade() const;
  20. //Operators
  21. bool operator < (course) const;
  22. bool operator > (course) const;
  23. course operator = (course);
  24. bool operator == (course) const;
  25. bool operator == (int n) const;
  26. bool operator != (course) const;
  27. };
  28.  
  29. //.... then in main
  30.  
  31. vector<course> cache; //holds courses in memory
  32. vector<course>::iterator point; //points at the cache
  33. course temp; //buffer
  34. fstream file;//for file I/O
And I'm trying to do file input and output as follows:
C++ Syntax (Toggle Plain Text)
  1. cout << "Loading file..." << endl;
  2. file.open("Courses.dat", ios::in | ios::binary);
  3. file.clear();
  4. file.read(reinterpret_cast<char *>(&temp), sizeof(temp));
  5. while (!file.eof()) {
  6. cache.push_back(temp);
  7. temp.print();
  8. file.read(reinterpret_cast<char *>(&temp), sizeof(temp));
  9. }
  10. file.close();
C++ Syntax (Toggle Plain Text)
  1. cout << "Saving to file..." << endl;
  2. file.open("Courses.dat", ios::out | ios::trunc | ios::binary);
  3. file.clear();
  4. for(point = cache.begin(); point != cache.end(); point++) {
  5. temp = *point;
  6. temp.print();
  7. file.write(reinterpret_cast<char *>(&temp), sizeof(temp));
  8. file.clear();
  9. }
  10. file.close();

What's interesting is if I write and read pre-made data like below, it works:
C++ Syntax (Toggle Plain Text)
  1. course one("CSCI", 2012, "C++ Programming 2", 3, 'A');
  2. course two("MATH", 2081, "Multiple Varible Calculus", 4, 'C');
  3. course three("ENGL", 1022, "Composition 2", 3, 'B');
  4. file.open("Courses.dat", ios::out | ios::trunc | ios::binary);
  5. file.write(reinterpret_cast<char *>(&one), sizeof(one));
  6. file.write(reinterpret_cast<char *>(&two), sizeof(two));
  7. file.write(reinterpret_cast<char *>(&three), sizeof(three));
  8. file.close();
  9.  
  10. //close program, open it again without writing that data
  11. //load data into cache, and it displays correctly
.But if I use any custom data (AKA user-input) it saves correctly as far as I can tell, but if I try to load the data it crashes when it tries to display it - printing out random gibberish.


Can anyone spot any errors I missed in the file I/O routines? If need be I can post the entire source code.
Thanks in advance for wading through this post!
Similar Threads
Reputation Points: 10
Solved Threads: 2
Newbie Poster
yesm is offline Offline
15 posts
since May 2007
May 4th, 2007
0

Re: Custom Class - File I/O

Your class doesn't meet the requirements for a POD type, so using read and write is undefined. Add a couple of member functions that serialize your class to and from a string, then use that string for file I/O.
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004
May 4th, 2007
0

Re: Custom Class - File I/O

Um... by that do you mean overload the << and >> operators?

I'm basing my work off my textbook ("Object-Oriented Programming in C++" by Robert Lafore"), who uses the following example:
c++ Syntax (Toggle Plain Text)
  1. // diskfun.cpp
  2. // reads and writes several objects to disk
  3. #include <fstream> //for file streams
  4. #include <iostream>
  5. using namespace std;
  6. ////////////////////////////////////////////////////////////////
  7. class person //class of persons
  8. {
  9. protected:
  10. char name[80]; //person's name
  11. int age; //person's age
  12. public:
  13. void getData() //get person's data
  14. {
  15. cout << "\n Enter name: "; cin >> name;
  16. cout << " Enter age: "; cin >> age;
  17. }
  18. void showData() //display person's data
  19. {
  20. cout << "\n Name: " << name;
  21. cout << "\n Age: " << age;
  22. }
  23. };
  24. ////////////////////////////////////////////////////////////////
  25. int main()
  26. {
  27. char ch;
  28. person pers; //create person object
  29. fstream file; //create input/output file
  30. //open for append
  31. file.open("GROUP.DAT", ios::app | ios::out |
  32. ios::in | ios::binary );
  33. do //data from user to file
  34. {
  35. cout << "\nEnter person's data:";
  36. pers.getData(); //get one person's data
  37. //write to file
  38. file.write( reinterpret_cast<char*>(&pers), sizeof(pers) );
  39. cout << "Enter another person (y/n)? ";
  40. cin >> ch;
  41. }
  42. while(ch=='y'); //quit on 'n'
  43. file.seekg(0); //reset to start of file
  44. //read first person
  45. file.read( reinterpret_cast<char*>(&pers), sizeof(pers) );
  46. while( !file.eof() ) //quit on EOF
  47. {
  48. cout << "\nPerson:"; //display person
  49. pers.showData(); //read another person
  50. file.read( reinterpret_cast<char*>(&pers), sizeof(pers) );
  51. }
  52. cout << endl;
  53. return 0;
  54. }

Do you mean because the strings are of undefined length, the file I/O messed up?
Reputation Points: 10
Solved Threads: 2
Newbie Poster
yesm is offline Offline
15 posts
since May 2007
May 4th, 2007
0

Re: Custom Class - File I/O

NOTE: Interestingly, when I tried again, here is the output:
CSCI 2012: C++ Programming 2
Worth 3 credits. Grade: A
MATH 2081: Multiple Varible Calculus
Worth 4 credits. Grade: C
ENGL 1022: Composition 2
Worth 3 credits. Grade: B
2022:
Worth 4 credits. Grade: C


Notice the last entry: it read the integers and char correctly, just missed the strings. Not crashing anymore...
Reputation Points: 10
Solved Threads: 2
Newbie Poster
yesm is offline Offline
15 posts
since May 2007
May 4th, 2007
0

Re: Custom Class - File I/O

>Um... by that do you mean overload the << and >> operators?
If you want. I think explicit serialize and deserialize member functions are more flexible though.

>I'm basing my work off my textbook ("Object-Oriented Programming in C++" by Robert Lafore")
You have my sympathy then. Lafore doesn't come to mind when I think of good writers, and he's on the list when I think of bad writers.

>Do you mean because the strings are of undefined length, the file I/O messed up?
I mean that your objects aren't guaranteed to be convertable to an array of unsigned char due to padding and other internal data structure. That's an absolute requirement when using read or write because you're casting your object to an array of char (roughly the same thing). Do a google search for "plain old data". Those are the rules you have to abide by if you want to be able to cast your objects to an unsigned char* (and you should be using unsigned char* rather than char*).

>Not crashing anymore...
Undefined behavior means anything could happen. It could work for a year and then crash every day for a month straight or vice versa.
Last edited by Narue; May 4th, 2007 at 12:47 pm.
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004
May 4th, 2007
0

Re: Custom Class - File I/O

Gaaaah, okay, now its crashing again...

Yea, I'm also using a textbook by Tony Gaddis, it's just not with me.

Hmm... so if I created a struct to hold my data, built a class around that struct, then wrote only the STRUCT to disk it would work better? I'll start on that, yell at me if I missed the boat again.


Sorry for the confuzzlement, I've never heard of any of this POD stuff, our professor just throws up powerpoints and hopes we get it ><
Reputation Points: 10
Solved Threads: 2
Newbie Poster
yesm is offline Offline
15 posts
since May 2007
May 4th, 2007
0

Re: Custom Class - File I/O

Wow. I have to re-write everything to deal with structs?
This sucks.
Reputation Points: 10
Solved Threads: 2
Newbie Poster
yesm is offline Offline
15 posts
since May 2007
May 4th, 2007
0

Re: Custom Class - File I/O

Ooooookay. So I re-wrote everything to write a struct to file, instead of a class. I made a struct called cinfo that I create from a class to write a file, and made a constructor to create a class from one of those structs (for reading data back in).

But the same exact error happens! I must be missing something different.

C++ Syntax (Toggle Plain Text)
  1. // This uses classes and STL to manage a listing of courses.
  2. // Created by:
  3. // Created: 5/3/07
  4. // Modified: 5/4/07
  5. #include <iostream>
  6. #include <iomanip>
  7. #include <fstream>
  8. #include <string>
  9. #include <vector>
  10. #include <algorithm>
  11. #include <iterator>
  12. #include <functional> // (?)
  13. using namespace std;
  14.  
  15. struct cinfo { //holds course info
  16. string prefix;
  17. int number;
  18. string title;
  19. int credits;
  20. char grade;
  21. };
  22.  
  23. class course {
  24. private:
  25. string prefix;
  26. int number;
  27. string title;
  28. int credits;
  29. char grade;
  30. public:
  31. //Constructors
  32. course();
  33. course(string, int, string, int, char);
  34. course(cinfo in);
  35. //Accessors
  36. void set();
  37. void print() const;
  38. string get_prefix() const;
  39. int get_number() const;
  40. string get_title() const;
  41. int get_credits() const;
  42. char get_grade() const;
  43. cinfo get_info() const;
  44. //Operators
  45. bool operator < (course) const;
  46. bool operator > (course) const;
  47. course operator = (course);
  48. bool operator == (course) const;
  49. bool operator == (int n) const;
  50. bool operator != (course) const;
  51. };
  52.  
  53. //class functions...
  54. //indenting below is a little screwed up, my bad
  55.  
  56. int main()
  57. {
  58. vector<course> cache; //holds courses in memory
  59. vector<course>::iterator point; //points at the cache
  60. cinfo temp //buffer struct
  61. course *buffer; //buffer class
  62. fstream file;//for file I/O
  63.  
  64. //stuff happens
  65.  
  66. file.open("Courses.dat", ios::out | ios::trunc | ios::binary);
  67. temp = one.get_info();
  68. file.write(reinterpret_cast<char *>(&temp), sizeof(temp));
  69. temp = two.get_info();
  70. file.write(reinterpret_cast<char *>(&temp), sizeof(temp));
  71. temp = three.get_info();
  72. file.write(reinterpret_cast<char *>(&temp), sizeof(temp));
  73. file.close();
  74.  
  75.  
  76.  
  77. cout << "Saving to file..." << endl;
  78. file.open("Courses.dat", ios::out | ios::trunc | ios::binary);
  79. file.clear();
  80. for(point = cache.begin(); point != cache.end(); point++) {
  81. temp = point->get_info();
  82. file.write(reinterpret_cast<char *>(&temp), sizeof(temp));
  83. file.clear();
  84. }
  85. file.close();//close file
  86.  
  87.  
  88.  
  89. cout << "Loading file..." << endl;
  90. file.open("Courses.dat", ios::in | ios::binary);
  91. file.clear();
  92. file.read(reinterpret_cast<char *>(&temp), sizeof(temp));
  93. while (!file.eof()) { //read in file
  94. buffer = new course(temp);
  95. cache.push_back(*buffer);//place object in cache
  96. delete buffer;
  97. file.read(reinterpret_cast<char *>(&temp), sizeof(temp));
  98. }
  99. file.close();

Attached is the entire source code. I cannot upload the blank "Courses.dat" file, so create a new ".txt" file in the same folder and rename it "Courses.dat" for it to work. The prompt at the beginning allows you to add three structs to file, so you don't have to type data every time you blank the .dat file.
Attached Files
File Type: cpp Program.cpp (10.8 KB, 19 views)
Reputation Points: 10
Solved Threads: 2
Newbie Poster
yesm is offline Offline
15 posts
since May 2007
May 4th, 2007
0

Re: Custom Class - File I/O

>Wow. I have to re-write everything to deal with structs?
No. You're so focused on trying to write an object to file, you're completely missing the point. All you need to do is turn the object into something that can be written to file. For example:
C++ Syntax (Toggle Plain Text)
  1. // Convert this to a pipe delimited string
  2. const string course::serialize()
  3. {
  4. stringstream out;
  5.  
  6. out<< prefix <<'|'<< number <<'|'<< title <<'|'<< credits <<'|'<< grade;
  7.  
  8. return out.str();
  9. }
Then you can do this:
C++ Syntax (Toggle Plain Text)
  1. file<< pers.serialize();
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004
May 4th, 2007
0

Re: Custom Class - File I/O

Oh, God.... we even did something like this a long time ago, I just didn't think we still wanted to use that method...

I'll whip up an in/out and let you know how it goes
Reputation Points: 10
Solved Threads: 2
Newbie Poster
yesm is offline Offline
15 posts
since May 2007

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: C++ in wxWidgets
Next Thread in C++ Forum Timeline: C Software Programming..





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC