tags:

views:

792

answers:

5

I have some c(++) code that uses sprintf to convert a uint_64 to a string. This needs to be portable to both linux and Solaris.

On linux we use %ju, but there does not appear to be any equivalent on Solaris. The closest I can find is %lu, but this produces incorrect output. Some sample code:

#include <stdio.h>
#include <sys/types.h>

#ifdef SunOS
typedef uint64_t u_int64_t;
#endif

int main(int argc, char **argv) {
    u_int64_t val = 123456789123L;

#ifdef SunOS
    printf("%lu\n", val);
#else
    printf("%ju\n", val);
#endif
}

On linux, the output is as expected; on Solaris 9 (don't ask), it's "28"

What can I use?

A: 

You can use %llu for long long. However, this is not very portable either, because long long isn't guaranteed to be 64 bits. :-)

Chris Jester-Young
+7  A: 

If you have have inttypes.h available you can use the macros it provides:

printf(  "%" PRIu64 "\n", val);

Not pretty (I seem to be saying that a lot recently), but it works.

Michael Burr
Awesome! This worked perfectly. Thanks!
Kris Pruden
A: 

You can get uint64_t from stdint.h if you want to avoid the SunOS conditional typedef.

Ted Percival
But you also need PRIu64 from <inttypes.h>, and that includes <stdint.h>.
Jonathan Leffler
Good point, thanks Jonathan :)
Ted Percival
+2  A: 

The answer depends on whether your code is actually C or C++. In C, you should be using an unsigned long long rather than another type (this is conformant to the current standard, and long long is pretty common as far as C99 support goes), appending ULL instead of L to your constant, and using (as has been mentioned) %llu as your specifier. If support for C99 doesn't exist, you may want to check the compiler documentation, as there is no other standard way to do it. long long is guarateed to be 64 bits at least.

coppro
uint64_t is every bit as standard as unsigned long long.
Jonathan Leffler
+4  A: 

On a C99 compliant system:

#include <inttypes.h>

uint64_t big = ...;
printf("%" PRIu64 "\n", big);

See section 7.8 of the C99 standard.

The specifiers are {PRI,SCN}[diouxX]{N,LEASTN,MAX,FASTN,PTR}

Where PRI is for the printf() family, SCN is for the scanf() family, d and i for signed integral types; o,u,x,X are for unsigned integral types as octal, decimal, hex, and Hex; N is one of the supported widths; LEAST and FAST correspond to those modifiers; PTR is for intptr_t; and MAX is for intmax_t.

wnoise