与inttypes.h、fscanf()、fprintf()不一致
Inconsistency with inttypes.h, fscanf(), fprintf()
我在使用 inttypes 时遇到了一些问题,这里用这个小代码示例进行了说明:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void print_byte(uint8_t b)
{
printf("%d%d%d%d%d%d%d%d\n",
!!(b & 128), !!(b & 64), !!(b & 32), !!(b & 16),
!!(b & 8), !!(b & 4), !!(b & 2), !!(b & 1));
}
int main()
{
FILE *f;
uint8_t bs = 8;
uint16_t bw = 100, bh = 200;
f = fopen("out", "w+");
print_byte(bs);
printf("%"PRIu8" %"PRIu16" %"PRIu16"\n", bs, bw, bh);
fprintf(f, "%"PRIu8"%"PRIu16"%"PRIu16, bs, bw, bh);
fclose(f);
f = fopen("out", "r");
fscanf(f, "%"SCNu8"%"SCNu16"%"SCNu16, &bs, &bw, &bh);
printf("%"PRIu8" %"PRIu16" %"PRIu16"\n", bs, bw, bh);
print_byte(bs);
fclose(f);
return 0;
}
给我
gcc -o test test.c && ./test
00001000
8 100 200
104 100 200
01101000
如果我在 fscanf 中将 SCNu8
更改为 SCNo8
,我会得到我应该得到的结果:
00001000
8 100 200
8 100 200
00001000
问题出在哪里?我不明白为什么它对第一个代码不起作用,但当我将该字节解释为八进制值时起作用。
问题是您的 text 文件中的值最终被合并在一起,如下所示:
8100200
这就是您无法正确读回数据的原因:fscanf
不知道第一个数字在哪里结束,下一个数字从哪里开始。
将空格放入 fprintf
格式行可解决此问题:
fprintf(f, "%"PRIu8" %"PRIu16" %"PRIu16, bs, bw, bh);
[fscanf
is] supposed to read a 1 byte value then two 2 bytes
fscanf
读取文本,而不是字节。如果您想写入字节,请使用库函数进行二进制输出和输入,即 fwrite
和 fread
:
// Writing in binary
f = fopen("out.bin", "wb");
fwrite(&bs, sizeof(bs), 1, f);
fwrite(&bw, sizeof(bw), 1, f);
fwrite(&bh, sizeof(bh), 1, f);
fclose(f);
// Reading in binary
f = fopen("out.bin", "rb");
fread(&bs, sizeof(bs), 1, f);
fread(&bw, sizeof(bw), 1, f);
fread(&bh, sizeof(bh), 1, f);
我在使用 inttypes 时遇到了一些问题,这里用这个小代码示例进行了说明:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void print_byte(uint8_t b)
{
printf("%d%d%d%d%d%d%d%d\n",
!!(b & 128), !!(b & 64), !!(b & 32), !!(b & 16),
!!(b & 8), !!(b & 4), !!(b & 2), !!(b & 1));
}
int main()
{
FILE *f;
uint8_t bs = 8;
uint16_t bw = 100, bh = 200;
f = fopen("out", "w+");
print_byte(bs);
printf("%"PRIu8" %"PRIu16" %"PRIu16"\n", bs, bw, bh);
fprintf(f, "%"PRIu8"%"PRIu16"%"PRIu16, bs, bw, bh);
fclose(f);
f = fopen("out", "r");
fscanf(f, "%"SCNu8"%"SCNu16"%"SCNu16, &bs, &bw, &bh);
printf("%"PRIu8" %"PRIu16" %"PRIu16"\n", bs, bw, bh);
print_byte(bs);
fclose(f);
return 0;
}
给我
gcc -o test test.c && ./test
00001000
8 100 200
104 100 200
01101000
如果我在 fscanf 中将 SCNu8
更改为 SCNo8
,我会得到我应该得到的结果:
00001000
8 100 200
8 100 200
00001000
问题出在哪里?我不明白为什么它对第一个代码不起作用,但当我将该字节解释为八进制值时起作用。
问题是您的 text 文件中的值最终被合并在一起,如下所示:
8100200
这就是您无法正确读回数据的原因:fscanf
不知道第一个数字在哪里结束,下一个数字从哪里开始。
将空格放入 fprintf
格式行可解决此问题:
fprintf(f, "%"PRIu8" %"PRIu16" %"PRIu16, bs, bw, bh);
[
fscanf
is] supposed to read a 1 byte value then two 2 bytes
fscanf
读取文本,而不是字节。如果您想写入字节,请使用库函数进行二进制输出和输入,即 fwrite
和 fread
:
// Writing in binary
f = fopen("out.bin", "wb");
fwrite(&bs, sizeof(bs), 1, f);
fwrite(&bw, sizeof(bw), 1, f);
fwrite(&bh, sizeof(bh), 1, f);
fclose(f);
// Reading in binary
f = fopen("out.bin", "rb");
fread(&bs, sizeof(bs), 1, f);
fread(&bw, sizeof(bw), 1, f);
fread(&bh, sizeof(bh), 1, f);