cancel
Showing results for 
Search instead for 
Did you mean: 

In CubeIDE, Can scanf() read an 8 character hexadecimal value, or is this a known bug?

LCott.1
Associate II

When I attempt to read an 8 character hexadecimal value with sscanf(), I get 0x7FFFFFFF for all values over "80000000". It's as if sscanf() is confusing signed and unsigned numbers. If I read the 8 characters as two sets of 4, there is no problem (this is my workaround). If I try this scaled down to 16 bits, there is no problem. If I put this same code in visual studio (with sscanf deprecation disabled), there is no problem. I'm just using "include <stdio.h>" to get sscanf() as it ships with CubeIDE.

The attached code snippet is for illustration. It only take lines 13-15 or 19-21 to recreate the problem.

int size32=sizeof(unsigned int);	//just to verify data sizes
    int size16=sizeof(unsigned short);	//just to verify data sizes
 
    //need to read in 8 characters as a 32 bit hex value
    char str1[]="12345678";
    unsigned int val1;
    int res1=sscanf(str1,"%8X",&val1);
 
    char str2[]="7F123456";
    unsigned int val2;
    int res2=sscanf(str2,"%8X",&val2);
 
    char str3[]="80123456";
    unsigned int val3;
    int res3=sscanf(str3,"%8X",&val3);
    //val3 should be 0x80123456, but sscanf returns 0x7FFFFFFF
    //THIS is the issue of this post
 
    char str4[]="FEDCBA98";
    unsigned int val4;
    int res4=sscanf(str4,"%8X",&val4);
    //val4 should be 0xFEDCBA98, but sscanf returns 0x7FFFFFFF
    //THIS is the issue of this post
 
    unsigned int val5,val6;
    int res5=sscanf(str4,"%4X%4X",&val5,&val6);
    unsigned int val7=(val5<<16)+val6;
    //scanned as separate 4+4 chars instead of 8, no problem
 
    //trying the same thing scaled down to 16 bits
    char str10[]="1234";
    unsigned short val10;
    int res10=sscanf(str10,"%4hX",&val10);
 
    char str11[]="FEDC";
    unsigned short val11;
    int res11=sscanf(str11,"%4hX",&val11);

0693W00000bhR15QAE.png

1 ACCEPTED SOLUTION

Accepted Solutions
LCE
Principal

Okay, so I found this:

https://stackoverflow.com/questions/26618443/how-to-use-int16-t-or-int32-t-with-functions-like-scanf

Still does NOT work with an upper case "X", but here it works with a lower case "x":

sscanf((char *)u8Uart3RxBuf, "%*s %*s %lx", &u32Val);

Bug or C standard?

View solution in original post

13 REPLIES 13
LCE
Principal

1st thing: try "%lX" in sscanf to read a 32 bit variable.

Next, try activating the float option in CubeIDE project settings, but I don't know if there's a connection between float and 32 bit integers with this option.

Pavel A.
Evangelist III

> 1st thing: try "%lX"

Tried, same result ((

It looks like a UB - signed int overflow. strtoul() parses unsigned 32-bit correctly but strtol (signed!) gives the same INT_MAX.

LCE
Principal

Wow, just found out it's not working here, what a bug!

I'm using that for over a year now, but I never put in hex numbers > 0x 7FFF FFFF, so I never came across this one.

So I get the same crap:

input hex 12345678
sscanf = 12345678
 
input hex abcdef12
sscanf = 7FFFFFFF
 
input hex 7f987641
sscanf = 7F987641
 
input hex 81231234
sscanf = 7FFFFFFF

So as @Pavel A.​  said, it treats the input hex number "partly" as signed.

LCE
Principal

Okay, so I found this:

https://stackoverflow.com/questions/26618443/how-to-use-int16-t-or-int32-t-with-functions-like-scanf

Still does NOT work with an upper case "X", but here it works with a lower case "x":

sscanf((char *)u8Uart3RxBuf, "%*s %*s %lx", &u32Val);

Bug or C standard?

LCE
Principal

@LCott.1​  So you already had the lower case "%x" in sscanf, maybe now try "unsigned long" = uint32_t for the variables?

LCE
Principal

Maybe the "use float" also affects other 32 bit variables for scanf?

0693W00000bhUJbQAM.png

LCott.1
Associate II

OK. Great. Lowe Case 'x' works fine but not Upper Case 'X".

We also played with the "Runtime library" setting above. With the "Reduced C" option, lower case x works, upper case X caps out at 0x7FFFFFFF, and 64 bit sscanf doesn't work at all ("%8llx" or "%llx").

With "Standard C" selected, Everything works correctly regardless of case or log or long long.

Who Knew?

I will use the lower case 'x' solution.

Thanks for all the help.

I haven't had any issues matching variable sizes to sscanf formats. It's just been that capital X, 7fffffff thing at issue. The "l", "ll" and "h" prefixes have been behaving as expected. That's also why I included the sizeof() stuff at the top of my code snippet. The compiler dutifully warns me if I mismatch.

Thanks for finding this!

One day it would have "fallen on my feet" as we say here...