How to write and read class from binary file in c++
The issue here isn't that you're reading or writing the bytes from disk incorrectly. Rather, the problem you're running into is that those bytes don't mean what you intend them to mean.
Your class has a data member name
that's a const char *
. That's a pointer to some location in memory that contains the name. When you use the write
function to write the data from your type to disk, it's storing that pointer on disk somewhere. When you then load the data from disk, it's reloading that pointer.
The problem is that the pointer isn't what you want to store. If you reload the pointer from disk, it'll point to the same spot in memory that it used to, but there's no reason to suspect that you'll find the student's name sitting in memory at the place it's pointing. If you've closed the program and then reopened it, you shouldn't see any memory from the previous run.
To fix this, you'll need to change how you write the data to disk. Instead of copying the raw bytes from the class, instead see if you can find a way to write out the name and the age in some way that you can then read that data back in. For example, maybe you'd write it to disk as the age, then a space, then the name.
Hope this helps!
How to write/read classes within classes to binary file C++
It should be immediately obvious that this code can't possibly work.
cFile.write(reinterpret_cast<char *>(&players[i]), sizeof(Character));
However big sizeof(Character)
is, we could have a Character
with an m_name
that takes up more bytes than that. So this code can't possibly be writing the character's name, and it clearly needs to do that.
Before you write anything to a file, decide on (and ideally, document) a file format at the byte level. Make sure your code writes in the format you documented and also can read in the format you documented. Skipping this step leads to pain and it also makes debugging impossible because you can't look at the file and compare it to a specification to see whether the writer or the reader is at fault.
Had you documented what bytes the player's name will occupy in the file, you'd immediately realize that you either need to have a variable-length object and encode the length somehow or pick a largest size name and allocate those many bytes. But because you skipped that vital step, you never actually worked out how to write a Character
to a file.
Reading and writing class objects to binary file
Imagine it this way, the class instance is just some memory chunk resting in your RAM, if you convert your class to a char pointer:
SomeClass someClassInstance;
char* data = reinterpret_cast<char*>(&someClassInstance);
It will point to the same data in your memory but it will be treated as a byte array in your program.
If you convert it back:
SomeClass* instance = reinterpret_cast<SomeClass*>(data);
It will be treated as the class again.
So in order to write your class to a file and later reconstruct it, you can just write the data
to some file which will be sizeof(SomeClass)
in size and later read the file and convert the raw bytes to the class instance.
However, keep in mind that you can only do this if your class is POD (Plain Old Data)!
How to write inputs into a binary file and read it in c?
I was wrong at writing into bin file and also reading from it.
First of all I need to thank to @lulle.
- As he mentioned in comments I changed
char*
in struct intochar
arrays.
char initials[80], name[250], email[100], acc_type[25];
And I also change file mode. I use
ab
to writing snippet. Andrb
in reading snippet.And I changed my writing snippet.
Here I looped over 12 times, this wrote every record 12 time. Sad ah?
This happened because I used just address of struct &new_acc
in fwrite
. If you use just address of a struct in fwrite`` or
fread``` it will write your whole struct. That's what happened to me. I wrote the whole struct 12 time.
for (int i = 0; i <= 12; ++i) // Looping 12 times
fwrite(&new_acc, sizeof(new_acc), 1, fp); // writting to file
So instead of looping I changed it into this
fwrite(&new_acc, sizeof(new_acc), 1, fp); \\ This line will write whole struct
But if you want to use members of struct instead of a whole struct, you are free to use a loop. Here is a example. This example is same as above one. But remember to use i
or any variable that you used in for
loop when writing to file. Instead of i
, if you used member name, It will also write 12 times (or as far as you are looping...)
for (int i = 0; i <= 12; ++i) // Looping 12 times
fwrite(&new_acc.[i], sizeof(new_acc.[i]), 1, fp); // writting to file
- And the same thing happened to reading part (I guess...).
So I changed the code snippet like below
FILE *fp;
fp = fopen("employees", "rb");
if (fp == NULL)
puts("Cannot open a file...");
int i = 0;
while(fread(&new_acc, sizeof(new_acc), 1, fp) != 0){ /* use fread one time */
printf("%d\n", new_acc.acc_num);
printf("%s\n", new_acc.name);
printf("%s\n", new_acc.initials);
printf("%s\n", new_acc.birth_day);
printf("%s\n", new_acc.address);
printf("%d\n", new_acc.phone);
printf("%s\n", new_acc.id_num);
printf("%s\n", new_acc.occupation);
printf("%s\n", new_acc.email);
printf("%s\n", new_acc.acc_type);
printf("%d\n", new_acc.balance);
++i;
}
fclose(fp);
Write and read object of class into and from binary file
The data is being buffered so it hasn't actually reached the file when you go to read it. Since you using two different objects to reference the in/out file, the OS has not clue how they are related.
You need to either flush the file:
mm.write(&out);
out.flush()
or close the file (which does an implicit flush):
mm.write(&out);
out.close()
You can also close the file by having the object go out of scope:
int main()
{
myc mm(3);
{
ofstream out("/tmp/output");
mm.write(&out);
}
...
}
Related Topics
C++ Std::Accumulate Doesn't Give the Expected Sum
C++ Overloaded Function as Template Argument
Base Pointer to Array of Derived Objects
Qt3D. Draw Transparent Qspheremesh Over Triangles
Ostream Chaining, Output Order
Diamond Inheritance Lowest Base Class Constructor
How to Use Cin.Fail() in C++ Properly
Can't Modify Char* - Memory Access Violation
What Is "Strip" (Gcc Application) Used For
How to Compile for Windows Xp with Visual Studio 2012
How to Use C++11 Enum Class for Flags