A practical guide to choosing the right C format specifiers for safe, portable, and readable output.
C format strings can be confusing, especially when dealing with cross-platform code or multiple compilers. This guide offers a practical reference for choosing the correct format specifier when printing various C types, including standard fixed-width integers and platform-specific types like size_t
.
Format String Decision Tree #
Assumption: You need to print a value with a size of 16, 32, or 64 bits using C99 format strings.
- Up to 16 bits: Use
%d
for signed and%u
for unsigned. No casting needed. - 32-bit values: Use
%ld
(signed) or%lu
(unsigned). Cast tolong
orunsigned long
. - 64-bit values: Use
%lld
(signed) or%llu
(unsigned). Cast tolong long
orunsigned long long
. size_t
: Use%zu
.- Hexadecimal:
- Up to 16-bit: Use
%x
or%X
. - 32-bit: Use
%lx
or%lX
. Cast tounsigned long
. - 64-bit: Use
%llx
or%llX
. Cast tounsigned long long
.
- Up to 16-bit: Use
Common Data Types and Format Strings #
Type | Format String | Notes |
---|---|---|
char |
%d |
Promoted to int . |
short |
%d |
Promoted to int . |
int |
%d |
Minimum width: 16-bit. |
long |
%ld |
Minimum width: 32-bit. |
long long |
%lld |
Minimum width: 64-bit. |
int8_t |
%d |
Promoted to int . |
int16_t |
%d |
Promoted to int . |
int32_t |
%ld |
Cast to long required. |
int64_t |
%lld |
Cast to long long required. |
unsigned char |
%d |
Promoted to int . |
unsigned short |
%u |
Promoted to int . |
unsigned int |
%u |
Minimum width: 16-bit. |
unsigned long |
%lu |
Minimum width: 32-bit. |
unsigned long long |
%llu |
Minimum width: 64-bit. |
uint8_t |
%u or %d |
Promoted to int . |
uint16_t |
%u |
Promoted to int . |
uint32_t |
%lu |
Cast to unsigned long required. |
uint64_t |
%llu |
Cast to unsigned long long required. |
size_t |
%zu |
Platform-dependent unsigned type. |
float |
%f or %g |
Promoted to double for printf . |
double |
%f or %g |
Standard floating-point format. |
void * |
%p |
Pointer address format. |
hex(uint8_t) |
%x or %X |
Lower/upper case hex. |
hex(uint16_t) |
%x or %X |
Lower/upper case hex. |
hex(uint32_t) |
%lx or %lX |
Cast to unsigned long . |
hex(uint64_t) |
%llx or %llX |
Cast to unsigned long long . |
For more information, refer to the POSIX fprintf
man page.