Reputation: 17230
I am writing some data to a file. Occasionally, I want to write a block of data from memory, and then move the put pointer along either 1, 2 or 3 bytes to maintain a 4 byte data boundary format.
I could make a new block of data containing zeros and write this, but this seems unnecessary and clumsy. How can I move the put pointer along 1, 2 or 3 bytes?
I am not sure how to do this, because if I call seekp()
surely I will move the pointer outside of the current file size? Whereas I assume ofstream.write()
deals with this correctly? ie: It resizes the file somehow while writing data?
Upvotes: 4
Views: 1613
Reputation: 21
I am assuming you are doing something like, except instead of writing two bytes of data you want to write 4 bytes with some padding.
#include <fstream>
using namespace std;
struct data
{
char first;
char second;
};
int _tmain(int argc, _TCHAR* argv[])
{
ofstream outFile;
data data1;
data data2;
data1.first = 'a';
data1.second = 'b';
data2.first = 'c';
data2.second = 'd';
outFile.open("somefile.dat");
outFile.write(reinterpret_cast<char*>(&data1), sizeof(data));
outFile.write(reinterpret_cast<char*>(&data2), sizeof(data));
outFile.close();
return 0;
}
One option is to simply make the struct 4 bytes. This could have a disadvantage as it could increase memory footprint.
Using seekp probably is not a good option, I tried it and it sort of worked but not really.
outFile.write(reinterpret_cast<char*>(&data1), sizeof(data));
outFile.seekp(2, ios_base::cur);
outFile.write(reinterpret_cast<char*>(&data2), sizeof(data));
outFile.seekp(2, ios_base::cur);
This did succeed in adding padding after data1 but not data2. Moving the pointer past the just isn't a good idea as it doesn't change the file size. I tried writing 0 bytes after seekp but this didn't work either.
Honestly I would implement a helper function to provide this functionality. Seems much cleaner this way. Here is a simple example:
#include <fstream>
using namespace std;
struct data
{
char first;
char second;
};
void WriteWithPadding(ofstream* outFile, data d, int width);
int _tmain(int argc, _TCHAR* argv[])
{
ofstream* outFile = new ofstream();
data data1;
data data2;
data1.first = 'a';
data1.second = 'b';
data2.first = 'c';
data2.second = 'd';
outFile->open("somefile.dat");
WriteWithPadding(outFile, data1, 4);
WriteWithPadding(outFile, data1, 4);
outFile->close();
delete outFile;
return 0;
}
void WriteWithPadding(ofstream* outFile, data d, int width)
{
if (sizeof(d) > width)
throw;
width = width - sizeof(d); // width is now amount of padding required
outFile->write(reinterpret_cast<char*>(&d), sizeof(data));
// Add Padding
for (int i = 0; i < width; i++)
{
outFile->put(0);
}
}
Upvotes: 1
Reputation: 10083
Just to be pedantic, I assume you have opened your file with ios::binary
, because you'll have issues if you haven't.
When writing a file, the file is only as large as the number of bytes you have written to your file. So if you write three bytes to the file, you will have a three-byte file.
To maintain a four-byte resolution, you must make sure to write four bytes at a time -- if you write a three-byte object, write an additional byte (zero?) to bring it up to four bytes.
Hope this helps.
Upvotes: 0