Search code examples
c++binaryfiles

Trouble outputting into a binary file in c++


In the book I'm reading, It started talking about binaries, and how we can output to a binary file similarly to how we can output to a text file. So I started reading more and wanted to give it a try; however, I've ran into what seems like a simple issue, but one that I'm not understanding properly considering my lack of understanding when it comes to binaries files.

So lets say I created a structure, and a function. Like the following.

struct celebrities 
{
    char name[15];
    char lastName[15];
};
void BinaryCreation(celebrities );
int main()
{
    celebrities actors = { "Denzel", "Washington" };

    BinaryCreation( actors);

    system("pause");

}

Now, I'll create a binary file:

void BinaryCreation(celebrities actors)
{

        fstream file;
        file.open("binaryfile.txt", ios::binary | ios::out);

Now, in the book it states that I should write something like the following to output it into binary:

file.write(address, size)

Which is where it gets confusing seeing as how if I have a structure, how exactly do I do that? I tried the following:

file.write(&actors.name, sizeof(actors.name));
file.write(&name, sizeof(name));

Also tried reinterpret cast. I also did the following

file.write(actors.name, sizeof(actors.name));

which worked in the sense of no errors, but it would output to file in text form (ASCII).

I'm sure this is very simple, and I'm overlooking something, but at the moment I can't figure it out.


Solution

  • The correct way to write the raw memory contents of the object would be:

    file.write(reinterpret_cast<char *>(&actors), sizeof(actors));
    

    but it would output to file in text form (ASCII).

    Well, your structure contains only text, so text is what you will see when you open it.

    Also I'm guessing that you did not open the file in a hex editor. If you did, you would see that each field occupies 15 bytes, regardless of whether the text contained in each character array occupies less space. The extra padding bytes between the fields may not be represented as printable characters in the program you were using to view the contents of the file.

    For example, given this program:

    #include <iostream>
    
    struct celebrities
    {
        char name[15];
        char lastName[15];
    };
    
    int main() {
        celebrities actors = { "Denzel", "Washington" };
    
        std::cout.write(reinterpret_cast<char *>(&actors), sizeof(actors));
    
        return 0;
    }
    

    Compiling this and piping the program's output to xxd gives the following:

    0000000: 4465 6e7a 656c 0000 0000 0000 0000 0057  Denzel.........W
    0000010: 6173 6869 6e67 746f 6e00 0000 0000       ashington.....
    

    Each field occupies exactly 15 bytes. The unused space after the null string terminator are additional null characters (byte 0). If you had previously stored a longer string one of the object's fields, you might see remnants of it in the output file.

    If we #include <cstring> and add this line directly above the call to std::cout.write() in the above program:

    std::strcpy(actors.lastName, "Whitaker");
    

    Running the program now produces this content:

    0000000: 4465 6e7a 656c 0000 0000 0000 0000 0057  Denzel.........W
    0000010: 6869 7461 6b65 7200 6e00 0000 0000       hitaker.n.....
    

    Note the lone n, left over from the end of the previous value, "Washington".