I have a homework and I have to write an object into a binary file. Then I have to read that object from the binary file. Everything works fine,except a variable of type char*. I read it, but at the end of the text i got some random characters. I think the problem is the string terminator /0 ,but i don't know how to handle it. Can someone help me?
This is the code I used to write in the file:
size_t n = strlen(input);// input is declared as char* input
f.write((char*)&n, sizeof(n 1));
f.write(input, n);
And this is how I tried to read this variable from the binary file:
size_t n;
f.read((char*)&n, sizeof(n));
delete[] buffer;// buffer is also a char*
buffer = new char[n];
f.read(buffer, n);
I got the text from variable input, but at the end i got some random characters
CodePudding user response:
C-strings must be nul-terminated
C-strings have length elements plus a terminating nul character. You do in fact write the nul to file, but you fail to allocate space for and read it from file. Make sure things match.
size_t n;
f.read( (char *)&n, sizeof n );
char * s = new char[n 1];
f.read( s, n 1 );
UPDATE: You have changed your code (as per commentary below) to not write the nul-terminator to file. Make sure to initialize it as such when you read it:
...
char * buffer = new char[n 1];
f.read( buffer, n );
buffer[n] = '\0';
Endianness nonsense you can totally ignore
As an aside, you are not considering endianness issues with your size_t
. I would personally make functions specifically for reading and writing integers in a file-specific endianness.
size_t n = read_integer( f, 4 );
char * s = new char[n 1];
f.read( s, n 1 );
Supposing a little-endian file, we could have:
size_t read_integer( std::istream & f, int n )
{
size_t result = 0;
while (n--)
result = (result << 8) | ((unsigned char)f.get() & 0xFF);
return result;
}
A corresponding function to write a little-endian value:
std::ostream & write_integer( std::ostream & f, size_t n, size_t value )
{
while (n--)
{
f.put( value & 0xFF );
value >>= 8;
}
return f;
}
(Untested. I might have goofed something.)
Oh, also:
write_integer( f, 4, strlen(s) );
f.write( s, strlen(s) 1 );