C ++二进制文件读入struct

时间:2011-12-01 22:59:56

标签: c++ struct ifstream

我使用结构编写了一个二进制文件,如下所示:

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]

3 个答案:

答案 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::setwstd::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检查的一个副作用是可以读取额外的行。