我想一次从二进制文件中读取8byte块,直到我到达文件末尾。为什么这段代码不起作用?有哪些替代方案?
// read a file into memory
#include <iostream>
#include <fstream>
using namespace std;
int main () {
long long int * buffer;
ifstream is;
is.open ("test.txt", ios::binary );
// allocate memory:
buffer = new long long int;
// read data:
while(!is.eof())
is.read (buffer,sizeof(long long int));
is.close();
delete[] buffer;
return 0;
}
如果我将所有long long int
替换为char
,则代码可以正常运行。
参考:代码改编自www.cplusplus.com
答案 0 :(得分:3)
问题是!eof:它会告诉您上次操作是否命中了eof,不是是否会显示下一个,而 不是上次是否失败!
在执行IO之后测试流的真实性本身(或使用失败的方法,这是相同的,否定的):
while (is.read(buffer, sizeof(long long int))) {
// use buffer
}
assert(is.fail()); // must be true
此外,您根本不必使用新内容:
long long buffer;
// ...
is.read(reinterpret_cast<char*>(&buffer), sizeof buffer)
// the reinterpret_cast is needed in your original code too
您的来源cplusplus.com在使用数据之前也无法检查读取是否成功。一般来说,我发现该网站非常适合列出参数,方法等,对其他大多数人来说都很可怕。
将所有内容放在一起,并提供一些示例输出:
#include <climits>
#include <fstream>
#include <iomanip>
#include <iostream>
int main () {
using namespace std;
ifstream in ("test.txt", in.binary);
cout << hex << setfill('0');
for (long long buffer;
in.read(reinterpret_cast<char*>(&buffer), sizeof buffer);)
{
cout << setw(sizeof buffer * CHAR_BIT / 4) << buffer << '\n';
}
return 0;
}
答案 1 :(得分:1)
进行缓冲区分配的另一种方法是使用union。这消除了铸造的需要。
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
union
{
long long int n;
char ch[sizeof(long long int)];
} buffer;
ifstream is("test.txt", ios::binary);
while (is.read(buffer.ch,sizeof(buffer)))
cout << buffer.n << '\n';
return 0;
}
答案 2 :(得分:0)
char buffer[8];
while (in.read(buffer,8)) {
long long data = *(reinterpret_cast<long long*>(buffer));
// process data
}
这可能就是你要找的东西。