问题描述
我想编程一个 16/32 位的 EEPROM。我正在从 C 程序写入文件,但 fwrite()
似乎只执行 8 位?我写了一个简单的例子,并使用xxd(和hexdump)查看结果,但文件似乎只有8位。我想知道我是不是因为 hexdump 和 xxd 的限制而只能看到 8 位,还是问题出在 fwrite()
上?
有谁知道我如何检查所有位是否都被写入文件?
#include <stdio.h>
#include <stdlib.h>
const unsigned int dataSize = 255;
unsigned long tmp[] = { 0xFFFF,0xFFDD,0xFDDD,0xF000,0x0F0F,0x0001,0x1010 };
int main() {
const char *path = "text.bin";
FILE *fp = fopen(path,"wb");
const void *data = tmp;
if (!fp) {
fprintf(stderr,"fopen() Failed for '%s'\n",path);
} else {
fwrite(data,1,dataSize,fp);
}
return 0;
}
使用 xxd 我明白了:
00000000: ffff 0000 0000 0000 ddff 0000 0000 0000 ................ 00000010: ddfd 0000 0000 0000 00f0 0000 0000 0000 ................ 00000020: 0f0f 0000 0000 0000 0100 0000 0000 0000 ................ 00000030: 1010 0000 0000 0000 0000 0000 0000 0000 ................ 00000040: c005 5182 b27f 0000 0000 0000 0000 0000 ..Q............. 00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000f0: 0000 0000 0000 0000 0000 0000 0000 00 ...............
编辑: 我试图确保有 32 位写入文件。 xxd 的结果是:
00000000: 11111111 11111111 00000000 00000000 00000000 00000000 ......
哪个显示 0xFFFF
有 16 位,但其他 16 位在哪里?理想情况下,对于 32 位边界,我希望看到 16 个零后跟 16 个 1 的 0xFFFF
。
我想知道这是否是 xxd 软件没有显示它的问题,而不是 C 没有编写它。
(我意识到名称和文件指针没有关闭,这只是我在 2 分钟内敲出以帮助显示问题的东西,我从空中挑选了 255。)
解决方法
要控制文件中的精确输出,您应该使用 <stdint.h>
中的精确宽度类型,而不是 unsigned long
,后者在您的系统上似乎有 64 位。
您没有看到 16 个零后跟 16 个 1 的原因是您的目标系统对大于 8 位的整数类型使用小端序表示。 Endianness 确定这些类型在内存中的字节顺序。
此外,您不应从大小为 28 字节的 tmp
数组中写入 255 字节。
这是修改后的版本:
#include <stdio.h>
#include <stdint.h>
// data has 256 bytes
uint32_t data[64] = { 0xFFFF,0xFFDD,0xFDDD,0xF000,0x0F0F,0x0001,0x1010 };
int main() {
const char *path = "text.bin";
FILE *fp = fopen(path,"wb");
if (!fp) {
fprintf(stderr,"fopen() failed for '%s'\n",path);
} else {
size_t written = fwrite(data,1,sizeof data,fp);
if (written != sizeof data) {
fprintf(stderr,"fwrite() only wrote %zu bytes\n",written);
}
fclose(fp);
}
return 0;
}
,
问题:16 位数据(2 字节)块存储在 64 位类型(8 字节)数组中。这解释了输出。
解决方案:
- 将 x 字节数据分配给“x 字节类型”(使用“固定宽度整数类型”)
- 写入确切的字节数(不要猜测)
请注意,0xFFFF 是 2 个字节。分配的数据为 7 * 2 = 14 个字节。 “tmp”数组为 7 * 8 = 56 字节。