大无符号整数的sscanf和%i/基数检测

大无符号整数的sscanf和%i/基数检测,c,scanf,unsigned,unsigned-integer,C,Scanf,Unsigned,Unsigned Integer,我正在处理包含大量数字(磁盘偏移)的文件,并且在使用%lli的scanf时遇到问题-数字的格式为0x。。。但是scanf不会读取所有位 下面是示例代码(我在上面测试过) 而我希望这两个数字相等 如果我使用%llx说明符,它工作正常,但我不想将自己限制为十六进制格式的数字。不幸的是I代表有符号的整数,相应的预期参数是指向int的指针;使用ll时,宽度将为long,但仍将被签名。对于带基检测的无符号整数,没有scanf格式字符 没有完美的解决方案。您可以使用strtoull(str,&endptr

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

下面是示例代码(我在上面测试过)

而我希望这两个数字相等


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

不幸的是
I
代表有符号的整数,相应的预期参数是指向
int
的指针;使用
ll
时,宽度将为
long
,但仍将被签名。对于带基检测的无符号整数,没有
scanf
格式字符


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


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

%lli
用于
长符号int
(在您的系统上,它只升到0x7fffffffffffffff)

%llu
表示
long unsigned int
(这是您试图读取的内容)


用前者代替后者。

试试@png谢谢-它可以工作,但我一次扫描多个令牌。这会使我所有的代码变得复杂。最好使用
snprintf()
而不是
sprintf()
来避免溢出。也许可以从@pmg的注释中添加
strtoull
的替代选项,我会将答案标记为正确。
#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