【问题标题】:using fscanf(file, %x, x) and converting hex to ints in C在 C 中使用 fscanf(file, %x, x) 并将十六进制转换为整数
【发布时间】:2013-12-10 02:57:45
【问题描述】:

我想使用 fscanf 来检查是否有十六进制数。 比如我想调用

if(fscanf(file,"%x", &u))

就像人们可以用字符串和整数来调用它一样。问题是这样的: 首先,你应该是什么类型? 其次,一旦我得到这个十六进制,即如果 if 语句通过,我如何将 u 转换为整数?

注意: 我想要

if(fscanf(file, "%x", &u) == 1)

如果读入的数字是 0x__ 则为真,否则为假。 我试过了

if(fscanf(file, "0x%x", &u) == 1)

但是对于十六进制数字返回 false

【问题讨论】:

  • 你知道吗,不管你怎么称呼它,无论是charintfloat,还是其他任何东西,归根结底,对于计算机来说,它都是二进制的?
  • 是的,我知道。但我需要将此数字转换为 int 类型,以便稍后测试 int

标签: c hex scanf


【解决方案1】:

来自scanf 手册页:

x, X 匹配一个可选带符号的十六进制整数;下一个指针必须是指向 unsigned int 的指针。

您无需执行任何操作即可将其转换为整数,这就是 scanf 为您所做的。

如果您特别想匹配0x___,请将其放入格式字符串中:

if (fscanf(file, "0x%x", &u) == 1)

我测试过的完整代码:

#include <stdio.h>
#include <unistd.h>

int main (int argc, char *argv[])
{
    unsigned int u;
    if (scanf("0x%x", &u) == 1) {
        printf("Read hex: %u\n", u);
    } else if (scanf("%u", &u) == 1) {
        printf("Read decimal: %u\n", u);
    }
}

【讨论】:

  • 所以“u”应该是一个无符号整数? if(fscanf(file,"%x", &u)) 将在读取 0x___ 格式的内容时返回 true?
  • 如果你想匹配0x,你可以明确添加:"0x%x",或者如果你想要0x0X之一,那么你可以使用"0%*[xX]%x"。当匹配有效时,fscanf() 的返回值将为 1(这是真的,但 EOF 的通常值 -1 也是如此)。养成测试预期匹配值数量的习惯——从长远来看这是最安全的。
  • 你也可以使用%i。如果它以0x 开头,它将把数字视为十六进制,如果它以0 开头,则将其视为八进制,否则将视为十进制。
  • 注意 - fscanf() 返回 匹配的参数数量,这就是为什么 ==1 测试是正确的。 @AlexKornhauser 正在测试 true - “任何非零值”。这是有风险的(在文件末尾,fscanf 将返回 EOF,如果我没记错的话是 -1:“真”,但“错”)。
  • 为什么不像我之前建议的那样使用%i
【解决方案2】:

@Barmar 上的讨论值得称赞。

通过sscanf()strtol() 以多种方式读取数据并对其进行处理。

unsigned u;
char buf[27];
if (scanf("%26[xX0-9A-Fa-f]", buf) != 1)
  ;//handle_bad_input();
else {
  char ch;
  if (sscanf(buf, "%u%c", &u, &ch) == 1)
    printf("decimal found %u", u);
  else if (sscanf(buf, "0x%X", &u) == 1)
    printf("hexadecimal found 0x%X", u);
  else
    ;//handle_bad_input();
  }

【讨论】:

  • 考虑做一个 fgetc 来检查 '0' 然后 'x' :/
  • @Alex Kornhauser 我宁愿建议更高级别的视图并使用fgets() 获取整行,然后将其处理为十进制或十六进制字符串。但这会影响更大的背景。一般来说,避免scanf(),当它无法按预期解析时,你就是SOL。我只是不知道驱动这个问题的更高层次的担忧会指向一个方向。
  • 好吧,我正在使用 fgets 和 fscanf 的组合。我把 0x___ 变成了一个字符串,详细说明它们是十六进制值,即 0x005 现在是 HEX 005。知道如何将 005 转换为 int 吗?你提到了 strtol 但我没有看到任何好的文档。我知道它跑题了,但我能举个例子吗?
  • @Alex Kornhauser 我希望你的意思是fgets()/sscanf() 而不是fgets()/fscanf()
  • @Alex Kornhauser 我没有看到具有strtol() 和“0x”前缀要求的强大简单解决方案。试试你的fgetc() 并在0 上进行测试。
猜你喜欢
  • 2010-10-16
  • 2011-08-11
  • 2014-04-16
  • 2017-08-12
  • 1970-01-01
  • 2016-12-04
相关资源
最近更新 更多