Home > Enterprise >  Reading an array of chars from a binary file into another array of chars dynamically allocated in C
Reading an array of chars from a binary file into another array of chars dynamically allocated in C

Time:12-29

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 );
  • Related