Записать в двоичный файл? - PullRequest
3 голосов
/ 08 апреля 2010

Вот структура данных с переменными:

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

Три переменные, qoh, Id_no & price, записываются правильно, но переменная "desc" неверна.Нужно ли инициализировать Part_record другим способом?Длина должна быть 20 символов.

Если у вас достаточно информации, поделитесь советами.

Ответы [ 5 ]

3 голосов
/ 08 апреля 2010

std::string хранит свои данные в динамически распределенной памяти, а не в структуре Part_record.

1 голос
/ 08 апреля 2010

Таким способом вы не можете записать std::string объекты (или любой из контейнеров STL) в файл. Они содержат внутренние указатели на свои данные, которые распределяются динамически; вы закончите записывать адреса указателей в ваш файл вместо содержимого строки.

Я бы рекомендовал использовать библиотеку iostream, если вам нужно записать std::string данные в файл. В противном случае вы можете получить доступ к символьным данным напрямую с помощью part.desc [0], чтобы добиться чего-то похожего на то, что вы пытаетесь:

fwrite(&part.desc[0], part.desc.size());
0 голосов
/ 08 апреля 2010

Запишите отдельные элементы в ваш выходной поток, или сделайте так, чтобы структура сделала это, или запишите отдельные элементы в буфер:

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;
      }
};

Поскольку у вас есть значения с плавающей точкой, целочисленные значения и текст, я весьма предлагаю вам использовать ASCII или текстовый формат, такой как CSV или XML. Двоичные версии чисел (целые и с плавающей запятой) могут быть несовместимы на разных платформах, между версиями ОС или даже версиями компилятора. Кроме того, текст переменной длины является трудной задачей в двоичных форматах.

0 голосов
/ 08 апреля 2010

std::string содержит указатели на реальные символьные данные, и вы сериализуете необработанную структуру, т.е. указатели.

Пишите каждую переменную отдельно, с особой обработкой для строки (т.е. используйте desc.data()и desc.size() для получения ptr и длины данных строки.)

0 голосов
/ 08 апреля 2010

string данные не будут записаны; вместо этого следует использовать char[20], поскольку string - это динамический класс, который не имеет фиксированного размера (технически он имеет фиксированный размер, но содержит указатель на динамический растущий массив символов).

Я говорю char[20], потому что вы упомянули, что строка должна быть 20 символов. Однако обязательно добавьте дополнительный символ для завершающего нулевого байта. Кроме того, ваш пример содержал строку с 25 пробелами, поэтому в этом случае вы хотели бы char[26].

Если у вас будут строки любого размера и вы не знаете максимального размера, вам придется сделать что-то более сложное, чем просто поместить все ваши данные в структуру.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...