Search code examples
cintscanfuint

sscanf seems to behave different on uint variables vs int variables in c


I am developing a microcontroller program and want to read digits from a string into integer variables using sscanf(). The problem is I get a different behavior when using int declarations vs uint8_t or uint16_t.

This is using int for variable declaration:

 #include <stdio.h>
 #include <stdint.h>
 int main()
 {
     int power;
     int hr;
     int cadence;
     sscanf("204 67 94","%d %d %d",&power, &hr, &cadence);
     printf("power: %d, hr: %d, cadence: %d", power, hr, cadence);        
     return 0;
 }

and when put into https://www.onlinegdb.com/ returns:

power: 204, hr: 67, cadence: 94

...Program finished with exit code 0
Press ENTER to exit console.

This is the way I would expect it to behave.


Whereas using uint8_t and uint16_t integers:

#include <stdio.h>
#include <stdint.h>
int main()
{
    uint16_t power;
    uint8_t hr;
    uint16_t cadence;
    sscanf("204 67 94","%d %d %d",&power, &hr, &cadence);
    printf("power: %d, hr: %d, cadence: %d", power, hr, cadence);
    return 0;
}

when put into https://www.onlinegdb.com/ delivers an output of:

power: 0, hr: 67, cadence: 94

...Program finished with exit code 0
 Press ENTER to exit console.

So for some reason power (or more general it seems the first variable) is set to 0. Could anybody please point me in the right direction and explain what I am doing wrong?


Solution

  • The correct format specifier would be

    scanf("%" SCNu16, &power);
    

    Using the wrong format specifier is Undefined behavior. You can do the same thing for sscanf too.

    sscanf("204","%"SCNu16 ,&power);
    

    Similarly for uint8_t it will be SCNu8. Similarly for printing you would use the correct one -

    printf("%" PRIu16 "\n", power);
    

    ALso compile your code with warnings enabled -gcc -Wall -Werror progname.c. The warnings you see - try to resolve them diligently. That would help you from big problems. Check the manual for sscanf to know that they return something - check it, to know whether sscanf call is sucessful or not.