2023-04-03 01:59 PM
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);
Solved! Go to Solution.
2023-04-04 03:26 AM
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?
2023-04-03 11:19 PM
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.
2023-04-04 12:48 AM
> 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.
2023-04-04 03:05 AM
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.
2023-04-04 03:26 AM
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?
2023-04-04 03:30 AM
@LCott.1 So you already had the lower case "%x" in sscanf, maybe now try "unsigned long" = uint32_t for the variables?
2023-04-04 03:59 AM
Maybe the "use float" also affects other 32 bit variables for scanf?
2023-04-04 02:24 PM
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.
2023-04-04 03:05 PM
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.
2023-04-04 11:13 PM
Thanks for finding this!
One day it would have "fallen on my feet" as we say here...