prev up next   top/contents search

comp.lang.c FAQ 列表· 问题 12.42

我该如何编写代码来符合这些旧的二进制数据文件格式?


这很困难,因为存在字大小和字节顺序的差异、浮点格式以及结构填充。为了获得您所需要的对这些细节的控制,您可能需要一次读取和写入一个字节,在移动和重新排列的过程中进行处理。(这并不总是听起来那么糟糕,并且可以使您的代码具有可移植性并提供完全的控制。)

例如,要从流fp中读取一个由字符、一个 32 位整数和一个 16 位整数组成的数据结构,并将其读入 C 结构

struct mystruct {
	char c;
	long int i32;
	int i16;
} s;
您可以使用类似这样的代码
	s.c = getc(fp);

	s.i32 = (long)getc(fp) << 24;
	s.i32 |= (long)getc(fp) << 16;
	s.i32 |= (unsigned)(getc(fp) << 8);
	s.i32 |= getc(fp);

	s.i16 = getc(fp) << 8;
	s.i16 |= getc(fp);
此代码假定getc读取 8 位字符,并且数据以最高有效字节在前(“大端”)的方式存储。转换为(long)可确保 16 位和 24 位移位操作在long值上进行(请参阅问题 3.14),转换为(unsigned)可防止符号扩展。(总的来说,在编写此类代码时使用所有unsigned类型更安全,但请参阅问题 3.19。)

相应地编写该结构可能看起来像

	putc(s.c, fp);

	putc((unsigned)((s.i32 >> 24) & 0xff), fp);
	putc((unsigned)((s.i32 >> 16) & 0xff), fp);
	putc((unsigned)((s.i32 >> 8) & 0xff), fp);
	putc((unsigned)(s.i32 & 0xff), fp);


	putc((s.i16 >> 8) & 0xff, fp);
	putc(s.i16 & 0xff, fp);

另请参阅问题 2.1212.3816.720.5


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管