rick irby
rick irby

Reputation: 31

Write to a binary file?

Here is data structure with variables:

struct Part_record
{
    char id_no[3];
    int qoh;
    string desc;
    double price:
};
---
(Using "cin" to input data)
---
Part_record null_part = {"  ", 0,"                         ",0.0};
---
---
file.seekg( -(long)sizeof(Part_record), ios::cur);
file.write( ( char *)&part, sizeof(Part_record) );

The three variables, qoh, Id_no & price, write out correctly, but the "desc" variable is not right. Do I need to initialize Part_record some other way? It should be 20 characters in length.

If you have enough info here, please share your advice.

Upvotes: 3

Views: 668

Answers (5)

Thomas Matthews
Thomas Matthews

Reputation: 57688

Write the individual members to your output stream, or have the structure do this, or write the individual members to a buffer:

struct Part_record
{
    char id_no[3];
    int qoh;
    string desc;
    double price:
// Block I/O methods
    size_t  Size_On_Stream(void) const
    {
      size_t size = 0;
      size = sizeof(id_no) + sizeof(goh) + sizeof(price);
      size += descr.length() + 1; // +1 for terminating null character
      return size;
    }
    void  Store_To_Buffer(unsigned char *& p_buffer) const
    {
       std::copy((unsigned char *)&id_no[0], (unsigned char *)&id_no[3], p_buffer);
       p_buffer += sizeof(id_no);
       std::copy((unsigned char *)&goh, (unsigned char *)(&goh) + sizeof(goh), p_buffer);
       p_buffer += sizeof(goh);
       std::copy((unsigned char *)&price, (unsigned char *)(&price) + sizeof(price), p_buffer);
       p_buffer += sizeof(price);
       strcpy(p_buffer, descr.str());
       p_buffer += descr.length();
       *p_buffer = 0x00;
       ++p_buffer;
       return;
     }
     void Write_To_Stream(ostream& output) const
     {
       size_t buffer_size = Size_On_Stream();
       unsigned char * buffer = new unsigned char [buffer_size];
       unsigned char * p_buffer = buffer;
       Store_To_Buffer(p_buffer);
       output.write((char *)buffer, buffer_size);
       delete [] buffer;
       return;
      }
};

Since you have floating point values, integer values and text, I highly suggest you use an ASCII or text based format such as CSV or XML. Binary versions of numbers (integral and floating point) may not be compatible across platforms, between OS versions or even compiler versions. Also, variable length text is a pain to deal with in binary formats.

Upvotes: 0

user229044
user229044

Reputation: 239311

You can't write std::string objects (or any of the STL containers) to a file in this way. They contain internal pointers to their data which is allocated dynamically; you'll wind up writing pointer addresses to your file, instead of the contents of the string.

I'd recommend using the iostream library if you need to write std::string data to a file. Failing that, you can access the character data directly with part.desc[0] to achieve something similar to what you're attempting:

fwrite(&part.desc[0], part.desc.size());

Upvotes: 1

Macke
Macke

Reputation: 25680

std::string contains pointers to the real character data, and you're serializing the raw structure, i.e. the pointers.

Write each variable separately, with special handling for the string (i.e. use desc.data() and desc.size() to get the ptr and length of the string's data.)

Upvotes: 0

Eli Courtwright
Eli Courtwright

Reputation: 192921

string data won't get written; you should use a char[20] instead, because string is a dynamic class which does not have a fixed size (technically it has a fixed size but contains a pointer to a dynamic, growable character array).

I say char[20] because you mentioned that the string should be 20 characters. However, be sure to include an extra character for the terminating null byte. Also, your example contained a string with 25 spaces, so in that case you'd want a char[26].

If you will have strings of any size and you don't know the max size, then you'll have to do something more complex than simply having all of your data in a struct.

Upvotes: 0

Kirill V. Lyadvinsky
Kirill V. Lyadvinsky

Reputation: 99585

std::string keeps its data in dynamically allocated memory, not in structure Part_record.

Upvotes: 3

Related Questions