2011-12-01 432 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檢查的一個副作用是可能會讀取額外的行。