c - 大无符号整数的 sscanf 和 %i/radix 检测

标签 c scanf unsigned unsigned-integer

我正在处理包含大量数字(磁盘偏移量)的文件,并且在使用 scanf for %lli 时遇到了问题 - 这些数字的格式为 0x... 但是 scanf 没有读取所有位。

这是示例代码(我在 https://www.onlinegdb.com/online_c_compiler 上测试过)。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char* str = malloc(30);
    unsigned long long l;
    sprintf(str, "0x%llx\n", 0xffffffffffffffffULL);
    printf("%s\n", str);
    sscanf(str, "%lli", &l);
    printf("%llx\n", l);

    return 0;
}

输出:

0xffffffffffffffff

7fffffffffffffff

而我希望两个数字相等。

如果我使用 %llx 说明符,它可以正常工作,但我不想将自己局限于十六进制格式的数字。

最佳答案

很遗憾,i代表有符号整数,对应的预期参数是指向int的指针;使用 ll 时,宽度将为 long long,但它仍会被签名。带碱基检测的无符号整数没有scanf格式字符。


没有完美的解决方案。您可以使用 strtoull(str, &endptr, 0)(甚至是 strtoumax),它会正确检测格式,但使用起来要繁琐得多。

但是 scanf 也不是完美的 - 如果数字太大,那么你总是会得到最大值,就像你得到 LLONG_MAX 一样,没有错误指示。

关于c - 大无符号整数的 sscanf 和 %i/radix 检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61991827/

相关文章:

c - fscanf 无法正确读取 float

c - 如何在 C 中的 scanf() 函数中使用无限类型说明符?

c - 为什么我的 fscanf 似乎没有读取任何内容?

mysql - 如何使用 mySQL 对负数进行位移以获得类似 Java、Python 等的结果?

c++ - 禁止隐式 `unsigned` 到 `double` 转换

c - C中的字符链表

c++ - inotify 未注册所有事件

MYSQL 查询减号运算符不起作用

c - Sprintf 关于格式化的警告

c - 使用 wsprintf 将 int 转换为 wchar_t*