【问题标题】:Write to a binary file?写入二进制文件?
【发布时间】:2010-04-07 20:53:48
【问题描述】:

这是带有变量的数据结构:

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 个字符。

如果您在这里有足够的信息,请分享您的建议。

【问题讨论】:

    标签: c++ file binary


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      如果您需要将std::string 数据写入文件,我建议您使用iostream 库。如果做不到这一点,您可以直接使用 part.desc[0] 访问字符数据,以实现与您正在尝试的类似的事情:

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

      【讨论】:

        【解决方案3】:

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

        我说char[20] 是因为您提到字符串应该是 20 个字符。但是,一定要为终止空字节包含一个额外的字符。此外,您的示例包含一个包含 25 个空格的字符串,因此在这种情况下,您需要一个 char[26]

        如果您将拥有任意大小的字符串并且您不知道最大大小,那么您将不得不做一些比将所有数据简单地放在一个结构中更复杂的事情。

        【讨论】:

        • 发帖者应该单独读取和写入每个元素,而不是对整个结构使用块 I/O。块 I/O 有很多孔,std::string 的字段就是其中之一。对于更快的 I/O,可以将结构的成员连续复制到缓冲区中,然后可以将缓冲区写为一个块。 OP 设计中的另一个漏洞是编译器可以在字段之间插入填充。
        【解决方案4】:

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

        分别编写每个变量,对字符串进行特殊处理(即使用desc.data()desc.size() 获取字符串数据的ptr 和长度。)

        【讨论】:

          【解决方案5】:

          将单个成员写入输出流,或让结构执行此操作,或将单个成员写入缓冲区:

          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。数字的二进制版本(整数和浮点)可能不兼容跨平台、操作系统版本甚至编译器版本。此外,以二进制格式处理可变长度文本也很麻烦。

          【讨论】:

            猜你喜欢
            • 2017-06-30
            • 2013-05-09
            • 2015-02-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多