【问题标题】:Inconsistency with inttypes.h, fscanf(), fprintf()与 inttypes.h、fscanf()、fprintf() 不一致
【发布时间】:2016-02-13 15:55:13
【问题描述】:

我在使用 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

问题出在哪里?我不明白为什么它对第一个代码不起作用,但是当我将该字节解释为八进制值时起作用。

【问题讨论】:

  • 如果我到处使用"%hhu%hu%hu"也会出现这个问题。
  • scanner 函数是棘手的野兽。你想测试他们返回的结果。
  • 还在阅读前将三个测试变量重置为 0 并获得启发... ;-)
  • 啊,是的,你是对的。我仍然不明白为什么需要这些空间。
  • scanf() 处理整数转换时,它会扫描可能是数字一部分的字符(除非您指定了长度:"%1" PRIu8 将只读取一个数字,但 @987654330 @ 将读取直到一个非数字),然后转换结果字符串。如果发生溢出,您会得到未定义的行为。

标签: c scanf stdint


【解决方案1】:

问题在于您的 text 文件中的值最终会合并在一起,如下所示:

8100200

这就是您无法正确读取数据的原因:fscanf 不知道第一个数字在哪里结束,下一个数字从哪里开始。

将空格放入fprintf 格式行可解决此问题:

fprintf(f, "%"PRIu8" %"PRIu16" %"PRIu16, bs, bw, bh);

[fscanf is] 应该读取一个 1 字节的值,然后读取两个 2 字节

fscanf 读取文本,而不是字节。如果您想写入字节,请使用库函数进行二进制输出和输入,即fwritefread

// 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);

【讨论】:

  • 我不太了解你,在这里。为什么 fscanf 需要分隔符?他应该读取一个 1 字节的值,然后读取两个 2 字节的值。
  • @user3618511:您希望使用bs = 1; bw = 2; bh = 3 读取的代码是什么?
  • 好吧,我写的是:1 2 和 3。
猜你喜欢
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
  • 2021-01-11
  • 1970-01-01
  • 2016-08-13
相关资源
最近更新 更多