我使用结构编写了一个二进制文件,如下所示:
struct block{
char data[32];
};
所以我最终得到的基本上是一个充满char [32]的大型二进制文件。数据在特定位置被格式化,因此获取特定信息并不困难。但是,我试着像这样读取文件:
int lines=0;
std::ifstream inputFile("file.bin",std::ios::binary);
while (!inputFile.eof())
{
inputFile.read(blocks[lines].data, sizeof(block));
lines++;
}
inputFile.close();
lines--;
然后像这样显示:
std::cout<<"block 1: "<<blocks[0].data<<std::endl;
// etc ...
我认为blocks [i] .data应该只给我一个属于索引i的char [32],但它却给了我每一个&#34;数据&#34;从该索引到结尾的结构中的元素。我确信这是我对其运作方式的误解。我的问题是:我如何得到由[[i] .data?
表示的char [32]答案 0 :(得分:2)
问题是您的std::cout
输出语句。当您尝试输出blocks[0].data
时,operator<<
得到的是不是 32个字符的数组,而是指向第一个字符的指针。这被解释为指向C字符串的指针,因此它会从那里输出在内存中找到的所有字符,直到找到'\0'
。由于每个数组元素只包含文件中的相应字符,因此输出文件的所有字符(除非文件中有'\0'
,然后输出就会停止)。此外,你似乎(非)幸运的是'\0'
跟随你的数据在内存中,所以输出停在那里(而不是继续输出内存中的任何内容,并可能在结束时给出分段错误进程的内存已达到。)
要输出32个字符作为字符,请使用std::cout.write(blocks[0].data,32)
。否则输出它们作为整数只是循环通过它们并将每一个转换为int:
for (int i = 0; i < 32; ++i)
std::cout << static_cast<int>(blocks[0].data[i]) << ' ';
当然,您可以使用所有流操作符来获取所需表单中的数字(例如std::hex
表示十六进制输出,和/或std::setw
和std::setfill
以获得固定宽度号码)。
答案 1 :(得分:1)
std::cout<<"block 1: "<<blocks[0].data<<std::endl;
您正在向流中发送char[]
,它会被提升为char*
,因此它认为它是一个以NULL结尾的字符串,并尝试将其显示为此类。很难说出你想要的是什么,但这将以十六进制显示:
std::cout << std::setfill('0') << std::hex;
for(int i=0; i<25; ++i)
std::cout << std::setw(2) << blocks[0].data[i];
std::cout << std::setfill(' ') << std::dec;
答案 2 :(得分:1)
您的输入部分需要更改:
while (inputFile.read(blocks[lines].data, sizeof(block))
{
lines++;
}
原因是直到 AFTER 发生读取操作时才确定EOF条件。使用EOF检查的一个副作用是可以读取额外的行。