写入二进制文件?

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和price被正确写出,但“desc”变量不正确。我需要用另一种方式初始化Part_record吗?它应该有20个字符长度。
如果您有足够的信息,请分享您的建议。
5个回答

3

std::string将其数据存储在动态分配的内存中,而不是结构体Part_record中。


1

你不能以这种方式将std::string对象(或任何STL容器)写入文件。它们包含对其动态分配的数据的内部指针;你最终会将指针地址写入文件,而不是字符串的内容。

如果需要将std::string数据写入文件,我建议使用iostream库。如果失败,请直接使用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。数字(整数和浮点数)的二进制版本可能在平台之间、操作系统版本之间甚至编译器版本之间不兼容。此外,可变长度文本在二进制格式中处理起来很麻烦。


0

string 数据不会被写入;你应该使用 char[20],因为 string 是一个动态类,它没有固定的大小(技术上它有一个固定的大小,但包含一个指向动态可增长字符数组的指针)。

我说 char[20],因为你提到字符串应该是 20 个字符。然而,请确保为终止空字节包括一个额外的字符。此外,你的示例包含了一个带有 25 个空格的字符串,所以在这种情况下,你需要一个 char[26]

如果你将有任何大小的字符串,并且你不知道最大大小,则必须做一些比仅仅在一个结构体中拥有所有数据更复杂的事情。


1
海报应该逐个读写每个元素,而不是使用整个结构的块I/O。块I/O中有许多漏洞,其中一个是带有std::string字段。为了更快的I/O,可以将结构的成员连续地复制到缓冲区中,然后将缓冲区作为一个块进行写入。OP设计中的另一个漏洞是编译器可以在字段之间插入填充。 - Thomas Matthews

0

std::string 包含指向实际字符数据的指针,您正在序列化原始结构,即指针。

将每个变量单独写入,特别处理字符串(即使用desc.data()desc.size()来获取字符串数据的指针和长度)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接