<inttypes.h> solves a portability trap: uint64_t may be unsigned long on one platform and unsigned long long on another. The format macros (PRIu64, PRIx64) expand to the correct printf/scanf specifier for each platform.
Use PRIu64, PRId64, etc. instead of guessing %llu or %lu.
This example prints fixed-width integers portably using the PRI macros.
// compile: gcc -o inttypesexample inttypesexample.c // run: ./inttypesexample // description: portable printf of fixed-width integers #include <inttypes.h> #include <stdio.h> int main() { uint8_t a = 255; uint32_t b = 0xDEADBEEF; uint64_t c = UINT64_MAX; int64_t d = INT64_MIN; printf("uint8: %" PRIu8 "\n", a); printf("uint32: %" PRIu32 " (0x%" PRIx32 ")\n", b, b); printf("uint64: %" PRIu64 "\n", c); printf("int64: %" PRId64 "\n", d); return 0; }
Format specifiers (for printf/scanf of fixed-width integers):
PRId8, PRId16, PRId32, PRId64: signed decimalPRIu8, PRIu16, PRIu32, PRIu64: unsigned decimalPRIx8, PRIx16, PRIx32, PRIx64: unsigned hex (lowercase)PRIX8, PRIX16, PRIX32, PRIX64: unsigned hex (uppercase)SCNd8, SCNd16, SCNd32, SCNd64: scanf format for signedSCNu8, SCNu16, SCNu32, SCNu64: scanf format for unsignedType limits:
INT8_MAX, INT16_MAX, INT32_MAX, INT64_MAX and _MIN variantsUINT8_MAX, UINT16_MAX, UINT32_MAX, UINT64_MAX