Click to See Complete Forum and Search --> : streams and files


chad101
October 10th, 2005, 12:40 PM
I’m having some problems with displaying my file content correctly .

I have a program that writes an object with two member items, in binary mode, to my “person.dat” file.

#include <iostream>
#include <fstream>
#include <stdlib.h>
class person
{
protected:
char name[80];
short age;
public:
void getData()
{
cout << "Enter name: "; cin >> name;
cout << "Enter age: "; cin >> age;
}
};
int main()
{
person pers;
pers.getData();

ofstream outfile ("person.dat", ios::binary);

outfile.write(reinterpret_cast<char*>(&pers), sizeof(pers));

cout << "finished" << endl;
system("PAUSE");
return 0;
}
Output
Enter name: Chad
Enter age: 24
finished


When I use another program to read this information I get very weird results.

#include <iostream>
#include <fstream>
#include <stdlib.h>
class person
{
protected:
char name[80];
short age;
public:
void showData()
{
cout << "Name: " << name << endl;
cout << "Age: " << age << endl;
}
};
int main()
{
person pers;
//pers.getData();

ifstream infile ("person.dat", ios::binary);

infile.read(reinterpret_cast<char*>(&pers), sizeof(pers));
pers.showData();
cout << "finished" << endl;
system("PAUSE");
return 0;
}

Output
Name: Hô|-wx;”
Age -96
finished

:confused:
I use DevC++ to compile my sources if that helps any

NOTE: This is not a homework problem. The source code can be found in “Object-Oriented Programming in C++”, Robert Lafore, Page 592.

jlou
October 10th, 2005, 12:42 PM
The code posted works fine, although it needs a using directive for the std namespace to compile on other compilers.

Make sure you are using the same .dat file for input and output, and not some leftover one from previous testing.

chad101
October 10th, 2005, 03:54 PM
I only have one .dat file in this directory.
It’s strange because everyone is saying it works yet I keep getting this “funky” number when I execute the infile program.

When I delete the ios::binary, it will work.

I’m stumped.

Is this due to me complieing it in DevC++? I know this complier is not the greatest.

SuperKoko
October 10th, 2005, 04:26 PM
Note that you must not read a non-POD type like that!
and your person class is a non-POD type, because it contains some non-public non-static members.
In fact, the problem does not comes from here (i am almost sure).
Your .dat file is probably invalid!
Look at it with a hex editor : the first bytes should be ASCII character, and then there should be a nul character, and some other characters, and finally the two last bytes (byte 80 and byte 81) should be the age (in little-endian format).

I compiled it with the MinGW's GCC (the compiler used with Dev C++), and it worked (after i added the using namespace std; directive).

Here is the binary person.dat file i manually generated with an hex editor:

00000000 54686174 27732061 206E616D 65000000 That's a name...
00000010 00000000 00000000 00000000 00000000 ................
00000020 00000000 00000000 00000000 00000000 ................
00000030 00000000 00000000 00000000 00000000 ................
00000040 00000000 00000000 00000000 00000000 ................
00000050 2A000000 *.

And the output i got:

Name: That's a name
Age: 42
finished
Appuyez sur une touche pour continuer . . .



Note : "Appuyez sur une touche pour continuer ..." is the french message for "Press any key to continue ..."

I am pretty sure that your file is invalid.
Verify it with an hex editor.
And if you don't understand, you can post the hex code of the file on this thread. So, we could determine if the file is really invalid or not.

chad101
October 10th, 2005, 05:39 PM
Your right, when I opened the person.dat file in a hex editor all I saw was two square looking figures

ٱ ڤ

I cannot read hex but it is nothing like the example above.

I emailed my professor and he said

“You might try switching to text mode file I/O. That will allow you to examine the data file with notepad.” Chuck

Even when I change person.dat to person.txt I get the same results. Oh well it’s simply an example in my text book that I wanted to look at.

The only way this program works for me is if I delete the ios::binary. And when I do this is what the file looks like in hex

00000000:63 68 61 64 00 3b 22 00 38 3b 22 00 08 00 00 00 chad.;".8;".....
00000010:55 8a c3 77 1b 41 a7 70 02 00 00 80 00 f0 fd 7f UŠÃw.A§p...€.ðý
00000020:29 00 00 00 02 00 00 00 30 ff 41 02 21 e9 c1 77 ).......0ÿA.!éÁw
00000030:70 ff 41 02 2d 10 40 00 00 50 41 00 04 50 41 00 pÿA.-.@..PA..PA.
00000040:68 ff 41 02 ff ff ff ff 6c ff 41 02 7f 03 00 00 hÿA.ÿÿÿÿlÿA....
00000050:18 00 ..



I appreciate the help.

Marc G
October 11th, 2005, 02:15 AM
Try to call memset(&name, 0, sizeof(name)) in the constructor of your Person class.

But again, this is not the recommended way of storing this person data into a file. You should add a Save and Load function to your person class which will save/load the individual member variables to the file.