2011-11-16 68 views
0

我有一個二進制文件和信息存儲格式的文檔。我試圖用C++編寫一個簡單的程序,它從文件中提取特定的信息,但我錯過了一些東西,因爲輸出不是我所期望的。基於二進制格式文檔訪問特定的二進制信息

文檔如下:

 
Half-word Field Name   Type Units Range  Precision 
10   Block Divider  INT*2 N/A  -1   N/A 
11-12  Latitude   INT*4 Degrees -90 to +90 0.001 

有該文件中的其他項目明顯,但這種情況下,我只是想獲得的緯度值。

我的代碼是:

#include <cstdlib> 
#include <iostream> 
#include <fstream> 

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    char* dataFileLocation = "testfile.bin"; 

    ifstream dataFile(dataFileLocation, ios::in | ios::binary); 

    if(dataFile.is_open()) 
    { 
    char* buffer = new char[32768]; 
    dataFile.seekg(10, ios::beg); 
    dataFile.read(buffer, 4); 
    dataFile.close(); 

    cout << "value is << (int)(buffer[0] & 255); 
    } 
} 

其結果是「值是226」,這是不在允許的範圍內。

我很新的這一點,這裏就是我的意圖,其中寫上面的代碼時:以二進制方式

    1. 打開文件從文件開始尋求到第11字節的
    2. 從此讀入4個字節
    3. 關閉文件
    4. 將這4個字節輸出爲整數。

    如果有人能指出我要出錯的地方,我一定會很感激。我不太瞭解(緩衝區[0] & 255)部分(從某些示例代碼中獲得),因此非常感謝非專業人士的條款。第一100個字節的

    進制轉儲:

    testfile.bin 98,402 bytes 11/16/2011 9:01:52 
          -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -A -B -C -D -E -F 
    
    00000000- 00 5F 3B BF 00 00 C4 17 00 00 00 E2 2E E0 00 00 [._;.............] 
    00000001- 00 03 FF FF 00 00 94 70 FF FE 81 30 00 00 00 5F [.......p...0..._] 
    00000002- 00 02 00 00 00 00 00 00 3B BF 00 00 C4 17 3B BF [........;.....;.] 
    00000003- 00 00 C4 17 00 00 00 00 00 00 00 00 80 02 00 00 [................] 
    00000004- 00 05 00 0A 00 0F 00 14 00 19 00 1E 00 23 00 28 [.............#.(] 
    00000005- 00 2D 00 32 00 37 00 3C 00 41 00 46 00 00 00 00 [.-.2.7.<.A.F....] 
    00000006- 00 00 00 00          [....   ] 
    
  • +2

    什麼是半字?什麼是int * 2,什麼是int * 4?偏移是基於零還是基於一個。另外:請添加(部分)一個hexdump到OQ。 – wildplasser

    +0

    @wildplasser:我的猜測是我們正在計算2個字節的單位,'int * k'的意思是「k字節的整數」... –

    +0

    這留下了從零開始的索引(以16位爲單位?)。順便說一句:IIRC汽車發動機控制工作在16位數量。但第二個想法:我不認爲他們存儲Lattitude ;-) – wildplasser

    回答

    3

    由於文檔列出的字段爲一個整數,但示出了精度爲0.001,我將認爲實際值所存儲的值乘以0.001 。整數範圍是-90000到90000.

    4個字節必須組合成一個整數。有兩種方法可以做到這一點,即大端和小端,而您需要的是依賴於寫文件的機器。例如x86個人電腦是小端。

    int little_endian = buffer[0] | buffer[1]<<8 | buffer[2]<<16 | buffer[3]<<24; 
    int big_endian = buffer[0]<<24 | buffer[1]<<16 | buffer[2]<<8 | buffer[3]; 
    

    &255用於刪除,當您轉換一個符號字符符號整數時出現的符號擴展。改用unsigned char,你可能不需要它。

    編輯:我覺得「半字」是指2個字節,所以你需要跳過20個字節,而不是10

    +0

    對於涉及2個字節的「半字」你是對的 - 非常感謝你,這是我的問題的關鍵! – TheOx