Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 写入二进制文件?_C++_File_Binary - Fatal编程技术网

C++ 写入二进制文件?

C++ 写入二进制文件?,c++,file,binary,C++,File,Binary,以下是带有变量的数据结构: 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_rec

以下是带有变量的数据结构:

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正确填写,但“描述” 变量不正确。 我是否需要以其他方式初始化Part_记录?它的长度应该是20个字符


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

std::string
将其数据保存在动态分配的内存中,而不是保存在结构
部分记录中
string
数据不会被写入;您应该改用
char[20]
,因为
string
是一个动态类,它没有固定的大小(从技术上讲,它有固定的大小,但包含指向动态的、可扩展的字符数组的指针)

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


如果您有任意大小的字符串,但不知道最大大小,那么您将不得不做一些更复杂的事情,而不仅仅是将所有数据都放在一个结构中。

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


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

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

如果需要将
std::string
数据写入文件,我建议使用
iostream
库。否则,您可以直接使用part.desc[0]访问字符数据,以实现类似于您正在尝试的功能:

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

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

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。数字的二进制版本(整数和浮点)可能在不同平台、操作系统版本甚至编译器版本之间不兼容。此外,在二进制格式中处理可变长度文本也是一件痛苦的事情。

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