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?
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With