I'm working with files containing large numbers (disk offsets) and have run into a problem using scanf
for %lli
- the numbers are of the format 0x
... but scanf
doesn't read all the bits.
Here's example code (I tested on 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;
}
It outputs:
0xffffffffffffffff
7fffffffffffffff
whereas I expect both numbers to be equal.
If I use the %llx
specifier, it works properly, but I don't want to limit myself to hex-formatted numbers.
Unfortunately i
stands for signed integer, and the corresponding expected argument is a pointer to int
; with ll
the width will be long long
, but it would still be signed. There is no scanf
format character for unsigned integer with base detection.
There is no perfect solution. You can use strtoull(str, &endptr, 0)
(or even strtoumax
), which will detect the format correctly, but it is much more tedious to use.
But scanf
is not perfect either - if the number is too big, then you would always get the maximum value, just like you got LLONG_MAX
, without error indication.