基于二进制格式文档访问特定二进制信息

时间:2011-11-16 20:37:42

标签: c++ binaryfiles

我有一个二进制文件和存储信息格式的文档。我正在尝试使用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. 以二进制模式打开文件
  2. 从文件开头搜索第11个字节
  3. 从该点读入4个字节
  4. 关闭文件
  5. 将这4个字节输出为整数。
  6. 如果有人能指出我出错的地方,我一定很感激。我真的不理解(buffer [0]&amp; 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                                        [....            ]
    

1 个答案:

答案 0 :(得分:3)

由于文档将字段列为整数但显示精度为0.001,我假设实际值是存储值乘以0.001。整数范围为-90000至90000。

必须将4个字节组合成一个整数。有两种方法可以做到这一点,big endian和little endian,你需要它们取决于编写文件的机器。例如,x86 PC是小端。

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用于删除将signed char转换为有符号整数时发生的符号扩展。使用unsigned char代替,你可能不需要它。

编辑:我认为“半字”是指2个字节,因此您需要跳过20个字节而不是10个字节。