Reputation: 1
Good day, I'm working on a program, which reads in a binary file (functions for read in are given and work) and then write the modified information back in another binary file. (I'm changing between two formats.) If I use std::cout to give out the numbers to the console right before (or after) I use ofstream to write them in a file. I get out the numbers I anticipate, but if I know input them into ofstream via << or write and then look at the contents of the file. (The conversion from this format to the original one exists and I can use it.) Then I get carbage.
struct Record {
unsigned latch;
float e, x, y, u, v, wt;}
I read in the given file and modify the numbers I read in. (The following is part of the main-function). Header h is defined and there exists a default constructor. phsp.read and copy are given and work. Reclen corresponds to the Record length and ensures, that the header is written right, because it can be different for different inputs.
std::ofstream outs;
outs.open(outfile, std::ios::out | std::ios::trunc);
Header h;
outs.write((char*) &h, reclen - 5);
for (int i=0; i<nMax; ++i){
phsp.read(mp);
copy(mp, ep);
Record rec;
Modify numbers and putting them into rec, which is a struct and given above. Rec should be written into the file
outs<<rec.latch<<rec.e<<rec.x<<rec.y<<rec.u<<rec.v<<rec.wt;
outs.write((char*) &rec.latch, 4);outs.write((char*) &rec.e, 4);
outs.write((char*) &rec.x, 4); outs.write((char*) &rec.y, 4);
outs.write((char*) &rec.u, 4);outs.write((char*) &rec.v, 4);
outs.write((char*) &rec.wt, 4);
outs.write((char*) &rec, reclen);
}
Not one of this writes, what I want into the file, but if I give out the numbers through std::cout and the console. I get the expected numbers.
std::cout<<rec.latch<<' '<<rec.e<<' '<<rec.x<<' '<<rec.y<<' '<<rec.u<<' '<<rec.v<<
' '<<rec.wt<<'\n';
I also checked the outs stream with good() and I also checked that the file is open. I can also write into the file. Also the write and the << output don't give the same output (could be expected). I checked the size of the rec.i and it also corresponds to the size of the structs. At the end I change the header again, because I have now new information.
outs.seekp(5);
outs.write((char*) &h, reclen - 5);
outs.close();
There I also have the same problem, with false numbers. I noticed that a number of 0 corresponds to 0, but the number 1 is converted to 16777216 for a unsigned int number.
I hope you can help me, I have no idea what is wrong.
Upvotes: 0
Views: 2503
Reputation: 5002
You need to decide whether your new file format is supposed to use binary or text representation for data.
Typically when you use ofstream::write()
method you're saving your data in binary format, which means it will be represented as an array of bytes with the length equal to the data structure you're writing. Therefore what you will find in the file will not be the number but its binary representation which generally looks like rubbish if seen as text.
You may see the number by using a hex editor, or you can read it back and then interpret it as a type of your choice. For example:
float number;
ifs.read(&number, sizeof(float); // read in the 4 bytes from the file into a float
This is an equivalent of doing:
char* buffer = new char[sizeof(float)];
ifs.read(buffer, sizeof(float)];
float f = *(reinterpret_cast<float*>(buffer));
If you printed out the contents of the buffer before casting it, you'd see the same rubbish you see in your file. Note that reading and writing binary data requires ios::binary
flag set.
operator<<
is typically used for writing data as text. It is less efficient in terms of space and speed, but has an advantage of being human readable. Writing data as text is as simple as printing it to the screen, e.g.
std::ofstream ofs;
ofs.open("file.txt");
float f = 1.337f;
ofs << "My float: " << f;
std::cout << "My float: " << f;
If you use above code in the same scope, there is no way for the contents in your file to be different from what's shown on your screen.
Finally make sure that your variables are initialized before using them, as in the code you've posted you're not doing it. E.g.
Header h; // <-- this probably contains rubbish until initialized with some values
outs.write((char*) &h, reclen - 5); // <-- writes rubbish
Upvotes: 1