3

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.

0

5 Answers 5

3

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

Sign up to request clarification or add additional context in comments.

Comments

1

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());

Comments

0

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.

1 Comment

The poster should read and write each element individually rather than using block I/O with the entire structure. There are many holes in the block I/O, and a field with std::string is one of them. For faster I/O, the members of the structure can be copied contiguously into a buffer, then the buffer can be written as one block. Another hole in the OP's design is the fact that the compile can insert padding between fields.
0

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.)

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.