为什么 basic_ifstream 显示错误的结果?
我有一个二进制文件。上半部分存储了2288*2288个经度浮点值,下半部分存储了相同数量的纬度浮点值。我使用以下代码将它们加载到浮点向量中。它可以像魅力一样运行,但给了我错误的结果。对于我的二进制文件,浮点向量应该填充总共2288*2288*2=10469888个元素,但只有159005个,它们的所有值都是相同的200.0000。您能解释一下我的代码有什么问题吗?
先感谢您!
bool LoadData(const char* pszDataFile)
{
typedef char_traits<float> traits_type;
typedef std::codecvt<float, char, mbstate_t> cvt;
std::basic_ifstream<float, traits_type> input( pszDataFile, std::ios::binary );
std::locale loc(std::locale(), new cvt());
input.imbue(loc);
std::vector<float> fvBuffer;
// Copies all data into buffer
std::copy(std::istreambuf_iterator<float>(input),
std::istreambuf_iterator<float>( ),
std::back_inserter(fvBuffer));
long nSzie = fvBuffer.size(); // Wrong vector size (159005)
return true;
}
I have a binary file. There are 2288*2288 longitude float values stored in top half section, and the same number of latitude float values occupied the bottom half. I used the following code to load them into a float vector. It can run like a charm, but gave me incorrect results. With regard to my binary file, the float vector should be filled with a total of 2288*2288*2=10469888 elements, but only 159005, all their values are the same 200.0000. Would you please explain what's wrong with my code?
Thank you in advance!
bool LoadData(const char* pszDataFile)
{
typedef char_traits<float> traits_type;
typedef std::codecvt<float, char, mbstate_t> cvt;
std::basic_ifstream<float, traits_type> input( pszDataFile, std::ios::binary );
std::locale loc(std::locale(), new cvt());
input.imbue(loc);
std::vector<float> fvBuffer;
// Copies all data into buffer
std::copy(std::istreambuf_iterator<float>(input),
std::istreambuf_iterator<float>( ),
std::back_inserter(fvBuffer));
long nSzie = fvBuffer.size(); // Wrong vector size (159005)
return true;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果在文件打开后使用 imbue() 文件流,则 imbue() 将默默失败。
您必须执行 imbue() 然后打开文件:
您的第二个问题是您混淆了术语二进制文件:
此代码使用运算符 >> 读取文本数据流(即文本文件)。
打开文件时使用 std::ios::binary 只会影响“行尾序列”(EOLS) 的生成方式,与文件的性质无关。不过,因为您指定了它,所以“\n”字符不会转换为 EOLS,这在生成二进制文件时很有用。
所以简短的答案是你更好地从文件中读取文本流。
您的向量比您预期的短的原因是因为流读取遇到错误,因此停止响应读取请求。
另外我无法编译你的代码。
所以你正在做一些不标准的事情。
If you imbue() a file stream after the file is opened the imbue() will silently fail.
You must do the imbue() then open the file:
Your second problem is you are confusing the terms binary file:
This code reads a stream of text data (i.e. a text file) using the operator >>
The use of
std::ios::binary
when you open the file only affects the how the 'end of line sequence' (EOLS) is generated it has nothing to do with the nature of the file. Though because you specify it the '\n' character is not converted into the EOLS which is useful when you are generating binary files.So the short answer is you better by reading a text stream from a file.
The reason your vector is shorter than what you expect is because the stream reading encountered an error and as a result stopped responding to read requests.
Additionally I can't get your code to compile.
So you are doing something else non-standard.
为了使 std::basic_ifstream 工作,您必须定义您的 Trait_type ,以便它提供输入流所需的所有内容,我不确定这是否可能。这将远远不仅仅是一个
codecvt
(您似乎认为它已经存在,而标准只需要 wchar_t、char 和 char, char 专业化)。如果您想要一个二进制输入迭代器,您必须自己编写一个来与 basic_ifstream 一起使用,如下所示(运行并给出预期结果,但不进一步调试):
To make std::basic_ifstream works, you have to define your trait_type so that it provides everything expected by input stream, and I'm not sure that it will be possible. That will be far more than just a
codecvt<float, char, mbstate_t>
(which you seem to think is already present while the standard demand only the wchar_t, char and char, char specializations).If you want a binary input iterator, you'll have to write one yourself to work with basic_ifstream, something like this (run and give the expected result, but not debugged further):