Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sprintf format for uint_fast16_t?

Tags:

c++

printf

I am having problem with format for uint_fast16_t

    uint_fast16_t runningOrderNo;

    std::string ATNativeConnector::_GetNextClOrdId()
{

    time_t t = time(NULL);
    struct tm* tim = localtime(&t);

    std::stringstream sstr;
    char temp[10];
    sprintf(temp, "%02d%02d%02d%03u", tim->tm_hour, tim->tm_min, tim->tm_sec, ++runningOrderNo);
    sstr << temp; //<< std::setfill('0') << std::setw(2) << tim->tm_hour << tim->tm_min <<  tim->tm_sec << ++runningOrderNo;
    runningOrderNo %= 999;

    //LOG4CXX_DEBUG(logger,"Generated " << sstr.str() << " second:" << tim->tm_sec << " order id");
    return sstr.str();
}

I get an warning like this.

ATNativeConnector.cpp:6156:95: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 6 has type ‘uint_fast16_t {aka long unsigned int}’ [-Wformat=]

I tried different formats from this page, will be thank full if someone will help me.

like image 286
Questioner Avatar asked Dec 14 '22 21:12

Questioner


2 Answers

The correct way would be to use the PRIuFAST16 macro from the page you linked:

sprintf(temp, "%02d%02d%02d%03" PRIuFAST16, ..., ++runningOrderNo);

The macro expands to a string, which is then joined by the preprocessor with adjacent string literals. This way the slightly strange looking "%02d%02d%02d%03" PRIuFAST16 ends up as one string literal containing the correct format specifier.

like image 145
sth Avatar answered Dec 31 '22 01:12

sth


Using the PRIuFAST16 macro, as sth's answer suggests, is the most correct solution.

An alternative (one that I find more readable) is to convert the argument to a known type. For example:

uintfast_16_t n = 42;
printf("%lu\n", (unsigned long)n);

You have to be careful to select a type that's wide enough to hold the value being converted; it's theoretically possible, but vanishingly unlikely, that uintfast_16_t could be wider than unsigned long. (In this case unsigned int is almost certainly good enough.)

If you're paranoid, use uintmax_t:

printf("%ju\n", (uintmax_t)n);

The advantage of this approach is that you and any readers of the code don't have to remember (or look up) the rather terse macro names.

The disadvantage is the risk of picking a type that's not wide enough and the (very minor) inefficiency of converting the operand to a wider type before printing it.

Of course using std::stringstream rather than sprintf avoids the issue altogether.

like image 34
Keith Thompson Avatar answered Dec 31 '22 01:12

Keith Thompson