2017-03-01 59 views
1

我正在研究現在的C++的二進制文件。我爲它製作了一個示例代碼,但效果不佳。從C++中的二進制文件獲取整數值時的垃圾值

#include <iostream> 
#include <fstream> 
using namespace std; 

int main() { 
    ofstream writeFile; 
    ifstream readFile; 
    int temp = 1; 

    writeFile.open("file.dat", ios::binary); 

    for (int i = 5; i <= 10 ; i++) // range 5 to 10 
     writeFile.write((char*)(&i), sizeof(i)); 

    writeFile.close(); 

    readFile.open("file.dat", ios::binary); 
    readFile.seekg(0); 
    while (!readFile.eof()) { 
     readFile.read((char*)(&temp), sizeof(temp)); 
     cout << "temp: " << temp << endl; 
     readFile >> ws; 
    } 
    readFile.close(); 

    system("pause"); 
    return 0; 
} 

下面是結果:

temp: 5 
temp: 6 
temp: 7 
temp: 8 
temp: 167772160 
temp: 167772160 

當我改變的範圍不包括圖9(例如,5〜8),它工作得很好。另外,當我使用double類型編碼時,它運行良好。所以我認爲整數9是問題。你能告訴我爲什麼嗎?

回答

4

readFile >> ws;丟棄白色空間,這對於二進制流是無意義的。在這種情況下,字符值9(即'\t')會被跳過,從而損壞您的流。只需刪除該行。

第二個問題是您沒有在讀取和顯示值之間檢查流的狀態。 EOF僅在之後檢測到,讀取將超過文件的結尾。這就是爲什麼你得到兩次無效值,第二次讀取失敗,並且只是將temp保留之前的值。 See this question瞭解更多詳情。

+0

值9實際上是'\ t'。 10是'\ n'。兩者都被認爲是空白的事實是導致問題的原因。 – IInspectable

+0

或者,'readFile >> ws'只會跳過'\ t'字符,然後讀取四個字節0​​0 00 00 0a,解釋爲小端4字節整數值爲167772160。明確定義(我相信)。但是,下一次嘗試讀取超出EOF。這是UB,並顯示167772160是未定義行爲的有效形式。 – IInspectable

1

The answer by François Andrieux已經回答了爲什麼你的代碼的行爲方式如此。

這裏有幾個方法來解決這個問題。

  1. 使用for循環讀取數字。它反映了用於寫入的循環。

    readFile.open("file.dat", ios::binary); 
    for (int i = 5; i <= 10 ; i++) 
    { 
        readFile.read((char*)(&temp), sizeof(temp)); 
        cout << "temp: " << temp << endl; 
    } 
    readFile.close(); 
    
  2. 正確使用while循環。

    readFile.open("file.dat", ios::binary); 
    while (readFile.read((char*)(&temp), sizeof(temp))) 
    { 
        cout << "temp: " << temp << endl; 
    } 
    readFile.close();