【问题标题】:why wifstream.read function is not reading data to variable?为什么 wifstream.read 函数没有将数据读取到变量中?
【发布时间】:2018-07-07 15:32:10
【问题描述】:

我的结构是:

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)); 和另一个也是,没有从文件中读取值到变量中。

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

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

提前感谢您的任何建议。

【问题讨论】:

  • 做 IO 并且没有错误检查是等待发生的灾难!因此使用未初始化数据的错误。
  • 我会记住这一点的谢谢@engf-010
  • 由于您不是以“正常”方式读取/写入wstring,更重要的是,因为您正在混合二进制数据,我建议您切换到ifstream/ofstream in二进制模式。但随后您将不得不将wofs.write(date.c_str(), s1); 更改为ofs.write((const char*)date.c_str(), s1 * sizeof(wchar_t)); 等等。此外,wchar_t date[sz]; 不是可移植代码,请改用wstring date; date.resize(sz);。此外,wchar_t 本身不可移植,因此请考虑将字符串以 UTF-8 格式保存到文件中。
  • @RemyLebeau 仍然在发生同样的事情
  • wchar_t date[sz]有什么问题;

标签: c++ file c++11 fstream


【解决方案1】:

与允许别名(char*)&integerstd::ofstream 不同,您不能使用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 有一个特殊的构造函数和fstreamopen 方法,它允许使用 Unicode 文件名,这将为处理具有 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,并使用标准库的输入/输出 &gt;&gt;/&lt;&lt; 运算符以纯文本形式写入整数。输出文件也将与 POSIX 兼容。

【讨论】:

    猜你喜欢
    • 2015-03-14
    • 1970-01-01
    • 2019-11-20
    • 2019-12-29
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 2021-08-24
    相关资源
    最近更新 更多