Question

I'm trying to convert from hexadecimal or decimal text to an unsigned int using the "%u" format specifier of sscanf. The result is not correct, for the value 0x01, sscanf is returning a 0 (0).

According to C++ Reference, the definition of "%u" specifier (highlighting is mine):
i, u Integer Any number of digits, optionally preceded by a sign (+ or -). Decimal digits assumed by default (0-9), but a 0 prefix introduces octal digits (0-7), and 0x hexadecimal digits (0-f).

According to Harbison & Steele, 3rd Edition:
The u conversion Unsigned decimal conversion is performed. ... The format of the number read is the same as expected for the input to the strtol function with the value 10 for the base argument; that is a sequence of decimal digits optionally preceded by - or +.

Note that one of the definitions allows "0x" to be specified in the string.

I am using IAR EW compiler with the compilation set to C99 dialect.

Which definition is correct for C99?

I am receiving two different results in the following program.

Here is a test program:

#include <stdio.h>
int main(void)
{
    const char text[] = "0x01 1";
    unsigned int first_value = 0U;
    unsigned int second_value = 0U;
    signed int   arguments_satisfied = 0;
    arguments_satisfied = sscanf(text, "%u %u", &first_value, &second_value);
    printf("Arguments scanned: %d, first: %d, second: %d\n",
        arguments_satisfied, first_value, second_value);
    return EXIT_SUCCESS;
}
Was it helpful?

Solution

According to the current C standard, C11, 7.21.6.2/12, only %i deduces the base from the context, all other specifiers fix the base:

i Matches an optionally signed integer, whose format is the same as expected for the subject sequence of the strtol function with the value 0 for the base argument. The corresponding argument shall be a pointer to signed integer.

o Matches an optionally signed octal integer, whose format is the same as expected for the subject sequence of the strtoul function with the value 8 for the base argument. The corresponding argument shall be a pointer to unsigned integer.

u Matches an optionally signed decimal integer, whose format is the same as expected for the subject sequence of the strtoul function with the value 10 for the base argument. The corresponding argument shall be a pointer to unsigned integer.

x Matches an optionally signed hexadecimal integer, whose format is the same as expected for the subject sequence of the strtoul function with the value 16 for the base argument. The corresponding argument shall be a pointer to unsigned integer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top