2017-01-04 50 views
3

我正在嘗試從二進制文件中讀取unsigned long號碼。
我在這個方式做這個:從二進制文件中讀取無符號long long

infile.open("file.bin", std::ios::in | std::ios::binary); 
    char* U=new char[sizeof(unsigned long)]; 
    unsigned long out=0; 
    infile.read(U, sizeof(unsigned long)); 
    out=static_cast<unsigned long>(*U); 
    delete[] U; 
    U=NULL; 
    infile.close(); 

,但結果是不正確的。
我的數據6A F2 6B 58 00 00 00 00女巫應被解讀爲1483469418但出於就是106在我的代碼這僅僅是數據

有什麼問題的第一個字節?
我應該如何正確地從文件中讀取unsigned long

+0

你期待什麼尾數格式,您使用的是什麼格式?在處理多字節整數值時要注意這一點非常重要。 – tadman

+0

您只是將第一個字節轉換爲無符號長整型。此外,由於遺忘,該方法無法移植。 –

+0

@tadman:文件和系統都是LE – RYN

回答

3

那是因爲你正在施放一個取消引用的值。即只有一個char不是完整的4個字節。 *U106

可以讀取數據,而無需中間緩衝器:

infile.read(reinterpret_cast<char*>(&out), sizeof out);

不同的是,在這裏你重新詮釋指針,而不是根據它的價值。

如果你仍然想使用緩衝區,它應該是*reinterpret_cast<unsigned long*>(U);,這也會重新解釋指針1st,然後解引用它。關鍵是取消引用適當類型的指針。指針的類型決定了該值使用了多少個字節。

+0

爲什麼使用新/錯誤類型的緩衝區的原因是什麼?爲什麼不把它轉化爲它所期望的價值呢? Endianess至少會讓我感到害怕... –

+0

恐怕我不完全理解你。使用緩衝區沒有錯,我沒有這麼說。在OPs中,這是多餘的,所以我實際上給出了一個將值直接存儲到變量中的例子。但是如果有人想使用緩衝區,那麼我有第二種選擇。如果需要,可以在轉換之前交換字節,但是OP似乎並不關心字節數。 – luk32

+0

啊廢話 - 我的壞..沒有看到什麼被定義爲 - 繼續:) –

1

嘗試out=*reinterpret_cast<unsigned long *>(U);

2

出=的static_cast(U);應該是out =(unsigned long *)(U);

它可以是簡單得多:

infile.open("file.bin", std::ios::in | std::ios::binary); 
unsigned long out=0; 
infile.read((char *)&out, sizeof(out)); 
infile.close(); 
1

你需要知道的文件(而不是程序)是否是大端或小端。然後讀取與龜etc字節()和reconsitute數量

所以

unsigned long read32be(FILE *fp) 
    { 
     unsigned long ch0, ch1, ch2 ch3; 

     ch0 = fgetc(fp); 
     ch1 = fgetc(fp); 
     ch2 = fgetc(fp); 
     ch3 = fgetc(fp); 

     return (unsigned long) (ch0 << 24) | (ch1 << 16) | (ch2 << 8) | ch3 
    } 

現在不管是否多頭是32位或64,或BIG_ENDIAN小端它將工作。如果文件是小端,則交換fgetc()的順序。

可移植地讀取二進制文件是非常棘手的。我已經把一些代碼在GitHub上

https://github.com/MalcolmMcLean/ieee754

+0

我會爭辯說,這是C,而不是C++,它根本沒有幫助。你建議OP交換所有的IO例程到C?無論如何,它都無法工作。您需要手動更改讀取順序。你可以用OP代碼來做同樣的事情。只需在'U'內容中使用'swap'。 – luk32

+0

無論機器的字節順序如何,它都可以工作。無論文件的字節順序如何,都無法正確解析文件。 –

+0

原始代碼也適用於機器永久性。把這兩件事分開是虛幻的。重要的是機器/系統和文件的永久性。如果兩者都相同,則沒有問題。如果它們不同,則需要交換字節。所以是的,可以正確地讀取文件,而不管它是否是endianes。你需要在具有相同字節的機器上閱讀它。我的觀點是,不可能做出一般情況,並且暗示某些事情可以工作,而不管是什麼情況,不管是什麼樣的條件字節交換都是煙霧和屏幕。你剛纔提出的問題。 – luk32