首页 > 解决方案 > 为什么 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));和另一个函数中,都没有将文件中的值读取到变量中。

传递给这两个函数的文件是二进制文件。

为什么它没有将值读取到变量中?解决办法是什么?

提前感谢您的任何建议。

标签: c++filec++11fstream

解决方案


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 兼容。


推荐阅读