Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Unable to convert number to uint8_t using sscanf

Hi,

I am trying to convert the string from ctime to a struct but i always get garbage values if i use "uint8_t". But i can get correct values if i use "int" datatype. I want to do it using uint8_t as it will save some space, as the numbers wont be above 255 anyway. Do i need unable some flags in the gcc Makefile?

UINT8_T:

struct time_struct {
char wday[4];
char month[4];
uint8_t month_num;
uint8_t mday;
uint8_t mil_hour;
uint8_t hour;
uint8_t min;
uint8_t sec;
int year;
};

struct time_struct now;

time_t epoch = 1548617880;
sscanf(ctime(&epoch),"%s %s %d %d:%d:%d %d",now->wday, now->month, &now->mday, &now->mil_hour, &now->min, &now->sec, &now->year);
NRF_LOG_INFO("%s %s %hhd",now->wday, now->month, now->mday);
NRF_LOG_INFO("%d:%d:%d %d", now->mil_hour, now->min, now->sec, now->year);
NRF_LOG_FLUSH();

//Output:
/*
<info> app: Sun Jan 27
<info> app: 19:38:6 2019
*/

INT:
struct time_struct {
char wday[4];
char month[4];
uint8_t month_num;
int mday;
int mil_hour;
uint8_t hour;
int min;
int sec;
int year;
};


struct time_struct now;

sscanf(ctime(&epoch),"%s %s %hhd %hhd:%hhd:%hhd %d",now->wday, now->month, &now->mday, &now->mil_hour, &now->min, &now->sec, &now->year);
NRF_LOG_INFO("%s %s %hhd",now->wday, now->month, now->mday);
NRF_LOG_INFO("%hhd:%hhd:%hhd %d", now->mil_hour, now->min, now->sec, now->year);
NRF_LOG_FLUSH();

// Output:
/*
<info> app: Sun Jan 27
<info> app: 0:65:34 19059
* /

thanks.

  • The sscanf() function requires that the destination for the "%d" conversion is 4 bytes - sizeof(int) wide. This will overwrite adjacent fields in your struct of uint8_t values.

    Workaround: Use temporary int variables on the stack.

  • then what format specifier should i use to convert to 1 byte? I have tried with %c as well, and it doesnt seem to work.

  • I use the following for 8-bit hex; %c probably works for 8-bit character. A lot depends on the settingf for the scanf library your compiler is using; I use IAR with full library (Use the full configuration of the C/C++ runtime library. Full locale interface, C locale, file descriptor support, multibytes in printf and scanf, and hex floats in strtod). If the IDE/compiler you use doesn't support some things, it is also possible to use your own sscanf by searching on the web for an example source which can be edited to be minimal.

    // 8-bit unsigned hex byte %hX:
       uint8_t AccRegisters[ACC_REGISTER_MAX_COUNT+1] = {0x40|0x38, 0x2A, 0x00, 0x25, 0x30, 0x30, 0x65};
       numValues = sscanf(p_data,"%hX %hX %hX %hX %hX %hX %hX",
                          &RequestStartIndex,                // Starting register index
                          &AccRequestRegisters[0],           //  0
                          &AccRequestRegisters[1],           //  1
                          &AccRequestRegisters[2],           //  2
                          &AccRequestRegisters[3],           //  3
                          &AccRequestRegisters[4],           //  4
                          &AccRequestRegisters[5]            //  5
                             );
    
    // 16-bit unsigned integer %hu:
       uint16_t Option;
       sscanf(p_data,"%hu", &Option);

    Also %hhu might work, depending on your library ..

  • No, %hhu does not work.  What library can i use? I am using the standard library with gcc Makefile. Do i need to add some compiler flags or something?

Related