Im new to file IO in C++.I couldnt find the problem with the following code.
There is actually data for 2 person in the dat file.But when I try to read,it prints out hundreds of results(until I close the program),although there is 88 byte information in the file.
#include <fstream.h> // for file streams
class person // class of persons
{
protected:
char name[40]; // person's name
int age; // person's age
public:
void getData(void) // get person's data
{
cout << "n Enter name: "; cin >> name;
cout << " Enter age: "; cin >> age;
}
void showData(void) // display person's data
{
cout << "n Name: " << name;
cout << "n Age: " << age;
}
};
int main()
{
char ch;
person pers; // create person object
fstream file; // create input/output file
// open for append
file.open("PERSON.DAT", ios::app | ios::out
| ios::in | ios::binary );
do // data from user to file
{
cout << "nEnter person's data:";
pers.getData(); // get one person's data
// write to file
file.write( (char*)&pers, sizeof(pers) );
cout << "Enter another person (y/n)? ";
cin >> ch;
}
while(ch=='y'); // quit on 'n'
file.seekg(0); // reset to start of file
// read first person
file.read( (char*)&pers, sizeof(pers) );
while( !file.eof() ) // quit on EOF
{
cout << "nPerson:"; // display person
pers.showData();
file.read( (char*)&pers, sizeof(pers) ); // read another
} // person
}
you didn't include <iostream> and usingnamespace std; ? you should return something in your last statement of your main... all i know is return 0; to terminate the program
I included iostream and return 0 is automatically added by the compiler,as I used so far.But I think the error is not associated with these.I still have the same problem.
I can read from that file iffff I create an ifstream object and open it using ios::binary.In this case,I read 2 objects as it should be.But what is wrong with the first post?
i don't really get it, if you're about to get the data from users why you should open a file? btw, you should: cout << "n <any printing on the screen>";
oldnewbie, I've copied and pasted your code exactly, and there's no problem
here's the code and output (tested on gcc 4.50 & microsoft 16.00.xxxx compilers)
#include <iostream>
#include <fstream>
class person // class of persons
{
protected:
char name[40]; // person's name
int age; // person's age
public:
void getData(void) // get person's data
{
std::cout << "\nEnter name: "; std::cin >> name;
std::cout << "\nEnter age: "; std::cin >> age;
}
void showData(void) // display person's data
{
std::cout << "\nName: " << name;
std::cout << "\nAge: " << age;
}
};
int main()
{
char ch;
person pers; // create person object
std::fstream file; // create input/output file
// open for append
file.open("PERSON.DAT", std::ios::app | std::ios::out | std::ios::in | std::ios::binary);
do // data from user to file
{
std::cout << "\nEnter person's data:";
pers.getData(); // get one person's data
// write to file
file.write( (char*)&pers, sizeof(pers) );
std::cout << "\nEnter another person (y/n)? ";
std::cin >> ch;
}while(ch=='y'); // quit on 'n'
file.seekg(0); // reset to start of file
// read first person
file.read( (char*)&pers, sizeof(pers) );
while( !file.eof() ) // quit on EOF
{
std::cout << "\nPerson:"; // display person
pers.showData();
file.read( (char*)&pers, sizeof(pers) ); // read another
} // person
return 0;
}
F:\pgm\code builder\cppquest01>cl main.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xlocale(323) : warning
C4530: C++ exception handler used, but unwind semantics are not enabled. Specify
/EHsc
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
main.obj
F:\pgm\code builder\cppquest01\>main
Enter person's data:
Enter name: matsom
Enter age: 44
Enter another person (y/n)? y
Enter person's data:
Enter name: oldnewbie
Enter age: 43
Enter another person (y/n)? y
Enter person's data:
Enter name: chipp
Enter age: 69
Enter another person (y/n)? n
Person:
Name: matsom
Age: 44
Person:
Name: oldnewbie
Age: 43
Person:
Name: chipp
Age: 69
i don't really get it, if you're about to get the data from users why you should open a file?
It is opened to append sth (if there is any data in the file before we open),and then ask the user to enter new data or display all data in the file.
Thanks matsom,
Im using wxDev-C++ IDE,but I have the problem I mentioned in first post.I can not open the file with
While I can open it with ifstream file("PERSON.DAT",ios::binary);
and read exactly what is in.In the first code (that one using fstream),when I check file after trying to open,it has zero value,but if I continue with that pointer,it reads hundreds of thousand of data from the file.(which has only 2 data)
What is the legal version of that?I took this code from the book that I'm studying.
BTW,do you think that "opening" part (opening both for read and write) is correct?
If I open the file just for reading (using ifstream object) and cout the file pointer,I see an adress value.But if I open it as in this code (fstream object,to read&write) and cout the pointer,what I see is 0.
If you want to save objects as binary data, you have to serialize them somehow. That is, figure out a binary representation for your class, and write the code yourself. The data a class pointer points to may contain all sorts of control data etc.
The bottom line is, don't ever cast a class pointer to a char*. If you need a binary representation, create a member function that returns one.
I dont know what is "to serialize".Also,until now I used (char*)&obj without any problem (it may be wrong as you said).But,I think the problem here is about "file opening part".
I found such a note on google search,I think this is about it.[using wxDev-C++]
Note: If you are a GNU g++ user (version 2.7.x or earlier), then do not use i/o mode flags when opening ifstream objects. Because of a bug in the GNU libg++ implementation, the flags will not be correctly interpreted. If you are working under Unix, omit the i/o mode flags entirely; if you are working with g++ under MS-DOS, then use an fstream object. This note applies to g++ users only.
If I wont use mode flags,how can I set the I/O mode with fstream or ifstream?
That's older than ancient. I doubt your version of g++ is that old, but if it is you should get a new one ASAP. Notice how the rest of that talks about DOS.
I dont know what is "to serialize"
Basically, you make up a format for a flat binary representation and create one for your objects following the format.
For example, if you had a Class X that had only an integer member, you could recreate objects of that class just from an integer value. Now you create a format for this (for example, "4 bytes for member x"). So a serialization of an X object would look like this in memory (Hex):
XX XX XX XX
PS: What I said earlier about that being illegal may or not be right, I am not entirely sure to be honest. But what I can guarantee you is that it doesn't make any sense to do that - unless you want to create a memory dump.
Thanks for your time hanst.
When I try to create fstream obj without i/o mode flags opening is successful.But this time it truncates the file(no append,since no ios::app).Anyway,although I have just upgraded g++ using package manager,I think the bug in above note is still valid.
I will work for that serialization.
g++ 2.7 is from the 1990's. That bug should, by no means, be still present nowadays. Instead of using the package manager (I have a hunch that it might be the same as the one from DevC++, which means it's horribly outdated and no longer maintained), you should probably just get MinGW (or GCC, depending on whether you are on windows or not) from their website.
PS: You probably won't need to worry about serialization for now, unless you want to get into network programming really soon or something like that.
For now,I solved that problem by closing the file and opening again for reading.[yes, package manager update didn't help]
BTW,since you mentioned network programming,a few days ago I searched for it since I want to do some amateur-level network coding.(at least hello-world of it,basic client-server).I prepared a list,if you know about them,which one would you suggest for a beginner,with keeping the details of low level as little as possible. Boost.asio | cpp netlib | poco | raknet