我有一个二进制文件和存储信息格式的文档。我正在尝试使用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”,不在允许的范围内。
我对此很陌生,这就是我在编写上述代码时的意图:
如果有人能指出我出错的地方,我一定很感激。我真的不理解(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 [.... ]
答案 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个字节。