c++ - 为什么 wifstream.read 函数没有将数据读取到变量中?
问题描述
我有一个结构是:
struct purchase_order_details{
wstring number;
wstring date;
wstring vender_code;
void Write(wofstream&);
void Read(wifstream&);
size_t totalSizeInFile;
};
上述功能实现如下:
void purchase_order_details::Write(wofstream& wofs)
{
size_t totalSize = 0;
size_t s1 = this->date.size(); totalSize += s1;
wofs.write((wchar_t*)&s1, sizeof(s1));
wofs.write( this->date.c_str() , s1 );
s1 = this->number.size(); totalSize += s1;
wofs.write((wchar_t*)&s1, sizeof(s1));
wofs.write( this->number.c_str() , s1 );
s1 = this->vender_code.size(); totalSize += s1;
wofs.write((wchar_t*)&s1, sizeof(s1));
wofs.write( this->vender_code.c_str() , s1 );
totalSizeInFile = totalSize;
}
void purchase_order_details::Read(wifstream& wifs)
{
size_t sz=0;
wifs.read((wchar_t*)&sz, sizeof(sz));
wchar_t * date = new wchar_t[sz];
wifs.read(date, sz);
this->date = date;
wifs.read((wchar_t*)&sz, sizeof(sz));
wchar_t * number = new wchar_t[sz];
wifs.read(number, sz);
this->number = number;
wifs.read((wchar_t*)&sz, sizeof(sz));
wchar_t * vcode = new wchar_t[sz];
wifs.read(vcode, sz);
this->vender_code = vcode;
delete []date;
delete []number;
delete []vcode;
}
因为我的结构包含一个wstring
因此我必须实现从文件中读取和写入数据的不同方法。
问题是在Read
函数wifs.read((wchar_t*)&sz, sizeof(sz));
和另一个函数中,都没有将文件中的值读取到变量中。
传递给这两个函数的文件是二进制文件。
为什么它没有将值读取到变量中?解决办法是什么?
提前感谢您的任何建议。
解决方案
与std::ofstream
允许别名不同的是(char*)&integer
,您不能使用std::wofstream
别名来写入二进制数据(wchar_t*)&integer
。您可以通过以下错误代码重现错误:
std::wofstream fout(L"unicode.txt", ios::binary);
int integer = 0x12345678;
fout.write((wchar_t*)&integer, sizeof(integer));
if(!fout.good())
cout << "problem\n"; //<- write fails, file size should be zero
的目的std::wstream
是将文件中的字节转换为宽字符,即2字节。如果您正在处理二进制数据,则您正在处理单个字节,因此请std::fstream
改用。
Visual Studio 有一个允许使用 Unicode 文件名的特殊构造函数和open
方法fstream
,这将为处理具有 Unicode 名称的文件提供必要的 Unicode 兼容性。
void Write(ofstream& ofs)
{
size_t sz = date.size();
ofs.write((char*)&sz, sizeof(sz)); ofs.write((char*)date.c_str(), sz);
sz = number.size();
ofs.write((char*)&sz, sizeof(sz)); ofs.write((char*)number.c_str(), sz);
sz = vender_code.size();
ofs.write((char*)&sz, sizeof(sz)); ofs.write((char*)vender_code.c_str(), sz);
}
void Read(std::ifstream& ifs)
{
size_t sz = 0;
ifs.read((char*)&sz, sizeof(sz)); date.resize(sz + 1, 0);
ifs.read((char*)&date[0], sz);
ifs.read((char*)&sz, sizeof(sz)); number.resize(sz + 1, 0);
ifs.read((char*)&number[0], sz);
ifs.read((char*)&sz, sizeof(sz)); vender_code.resize(sz + 1, 0);
ifs.read((char*)&vender_code[0], sz);
}
并确保以二进制模式打开文件:
purchase_order_details info;
info.date = L"date";
info.number = L"number";
info.vender_code = L"vendor_code";
ofstream fout(L"unicode.txt", std::ios::binary);
info.Write(fout);
fout.close();
ifstream fin(L"unicode.txt", std::ios::binary);
info.Read(fin);
或者,将 Unicode 从 UTF16 转换为 UTF8,并使用标准库的输入/输出>>
/<<
运算符以纯文本形式写入整数。输出文件也将与 POSIX 兼容。
推荐阅读
- jenkins - Jenkins MSTest + MSTestPublisher 在测试失败时不会失败构建
- android - 将 CardView 的高度设置为屏幕大小的自定义百分比
- python - 将 Acrobat Reader 嵌入 PyQt5 应用程序导致空白页 [PyQt5]
- php - PHP imap_search:搜索 UTF-8 / 支持 UTF-8 的非 ASCII 字符
- generics - Kotlin 接口构造函数
- java - 关于 Spring 框架中的 AnnotationConfigApplicationContext
- excel - vba:如何为每个循环使用多个 If、Else 条件和基于动态标准的公式?
- angular - 无法运行 Angular 站点,因为我的 angular.json 文件路径与 ng build 创建的不匹配
- swift - 获取 CollectionView 内所有 collectionViewCells 高度的总和
- android - Android 客户端上的 Firestore 集合组 PERMISSION_DENIED