sscanf 和 %i / 大无符号整数的基数检测
sscanf and %i / radix detection of large unsigned integers
我正在处理包含大量数字(磁盘偏移量)的文件,并且 运行 使用 scanf
for %lli
时遇到问题 - 数字的格式为 [=14] =]...但是 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
一样,没有错误提示。
%lli
用于 long long signed int
(在您的系统上只能达到 0x7fffffffffffffff)。
%llu
用于 long long unsigned int
(这是您要阅读的内容)。
前者换后者。
我正在处理包含大量数字(磁盘偏移量)的文件,并且 运行 使用 scanf
for %lli
时遇到问题 - 数字的格式为 [=14] =]...但是 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
一样,没有错误提示。
%lli
用于 long long signed int
(在您的系统上只能达到 0x7fffffffffffffff)。
%llu
用于 long long unsigned int
(这是您要阅读的内容)。
前者换后者。