2010-04-07 5 views
3

Вот структура данных с переменными:Запись в двоичный файл?

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 & цена, написать правильно, но «убывание» переменная не является правильным. Нужно ли инициализировать Part_record каким-то другим способом? Длина должна быть 20 символов.

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

ответ

3

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

0

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

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

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

+1

Плакат должен читать и писать каждый элемент отдельно, а не использовать блок ввода-вывода со всей структурой. В блоке ввода-вывода много дыр, и поле с 'std :: string' является одним из них. Для более быстрого ввода-вывода члены структуры могут быть скопированы * смежно * в буфер, тогда буфер можно записать как один блок.Еще одно отверстие в дизайне OP - это тот факт, что компилятор может вставлять отступы между полями. –

0

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

Написать каждый переменный отдельно, со специальной обработкой для строки (т.е. использовать desc.data() и desc.size() получить PTR и длину данных струны.)

1

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

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

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

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

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. Двоичные версии чисел (интегральные и с плавающей запятой) могут быть несовместимы между платформами, между версиями ОС и даже версиями компилятора. Кроме того, текст переменной длины - это боль, с которой приходится иметь дело в двоичных форматах.

Смежные вопросы