Code Yarns ‍👨‍💻
Tech BlogPersonal Blog

cinttypes macros

📅 2019-Dec-30 ⬩ ✍️ Ashwin Nanjappa ⬩ 📚 Archive

Using fixed width integer types, such as int32_t, from the cstdint header file is important for writing portable C++ code. Once you are using such fixed width types, how do you print them using printf or read them in using scanf? This is the problem that the macros defined in the cinttypes header file were created to solve.

The C++11 standard succintly lists the cinttypes macros as:

PRI{d i o u x X}[FAST LEAST]{8 16 32 64}
PRI{d i o u x X}{MAX PTR}
SCN{d i o u x X}[FAST LEAST]{8 16 32 64}
SCN{d i o u x X}{MAX PTR}

What this means is that you can use the macro PRIi32 as the format specifier in printf for an int32_t variable. Or if you want to scan in an uint8_t variable, then use the SCNu8 macro and so on.

These macros define the correct format specifier character, so using them entails combining string literals. Their usage is illustrated by this code example:

// Classic types

int i;
scanf("%i\n", &i);
printf("%i\n", i);

// Fixed width types

#include <cinttypes>

int32_t i32;
scanf("%" SCNi32 "\n", &i32);
printf("%" PRIi32 "\n", i32);  // Print int value
printf("%" PRIx32 "\n", i32);  // Print int value as hex

uint8_t u8;
scanf("%" SCNu8 "\n", &u8);
printf("%" PRIu8 "\n", u8);

Note that the C++ standard says that cinttypes will include cstdint, so the latter header does not need to be included if you are using these macros.