2011-12-01 224 views
0

我已经使用一个结构如下写入二进制文件:C++二进制文件读入结构

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 ... 

我以为块[I]。数据应该只是给我的char [32]它属于索引i,但它将结构中的每个“data”元素都从该索引提供给结构的末尾。我相信这是我对这种工作原理的误解。我的问题是:我如何才能获得由块[i] .data表示的char [32]?

回答

2

的问题是你的std::cout输出语句。当您尝试输出blocks[0].data时,operator<<得到的是而不是 32个字符的数组,但指向第一个字符的指针。这被解释为指向C字符串的指针,因此它将输出从内存中找到的所有字符,直到找到'\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以获得固定宽度数字)。

+0

std :: cout.write做的伎俩。该阵列正在适当填充;这只是我使用的输出方法。谢谢。 –

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; 
1

你输入部分需要改变:

while (inputFile.read(blocks[lines].data, sizeof(block)) 
{ 
    lines++; 
} 

的原因是EOF条件没有被确定直到AFTER发生读取操作。您使用EOF检查的一个副作用是可能会读取额外的行。