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设计中的另一个漏洞是编译器可以在字段之间插入填充。