# fmtlib Standard Format Specifiers: Complete Reference for printf-Style Syntax

> Explore fmtlib standard format specifiers for printf style syntax. Discover d/i/u, o, x/X, f/F, e/E, g/G, a/A, c, s, and p specifiers for powerful string formatting.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: api-reference
- Published: 2026-09-08

---

**The {fmt} library supports twelve core conversion specifiers—`d/i/u`, `o`, `x/X`, `f/F`, `e/E`, `g/G`, `a/A`, `c`, `s`, and `p`—that map to internal presentation types defined in [`include/fmt/printf.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/printf.h).**

The {fmt} library provides a high-performance formatting implementation compatible with both modern `{}`-style formatting and traditional C printf-style syntax. Understanding the standard format specifiers available in **fmtlib** helps developers write portable, efficient formatting code. The specifier parsing logic resides primarily in [`include/fmt/printf.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/printf.h), where the `parse_printf_presentation_type` function converts each format character into an internal presentation type.

## Integer Format Specifiers in fmtlib

The integer format specifiers in **fmtlib format specifiers** follow standard C conventions with full signed and unsigned support.

### Decimal and Unsigned Integers

- **`d`** / **`i`** — signed decimal integer, maps to internal `dec` presentation type
- **`u`** — unsigned decimal integer, also maps to `dec`

```cpp
fmt::printf("%d", -42);     // → -42
fmt::printf("%i", 42);      // → 42
fmt::printf("%u", 42);      // → 42

```

### Octal and Hexadecimal Integers

- **`o`** — octal integer, maps to internal `oct` presentation type
- **`x`** — hexadecimal integer (lowercase), maps to `hex`
- **`X`** — hexadecimal integer (uppercase), maps to `hex`

```cpp
fmt::printf("%o", 10);          // → 12
fmt::printf("%08x", 255);       // → 000000ff
fmt::printf("%#X", 255);        // → 0XFF

```

## Floating-Point Format Specifiers in fmtlib

**fmtlib floating-point specifiers** provide four distinct presentation modes for real numbers.

### Fixed and Scientific Notation

- **`f`** / **`F`** — fixed-point notation, maps to internal `fixed` presentation type
- **`e`** / **`E`** — scientific (exponential) notation, maps to `exp`

```cpp
fmt::printf("%f", 3.14159);     // → 3.141590
fmt::printf("%+.2e", 0.001);    // → +1.00e-03
fmt::printf("%E", 1234.5);      // → 1.234500E+03

```

### General and Hexadecimal Formats

- **`g`** / **`G`** — general format (chooses fixed or scientific based on magnitude), maps to `general`
- **`a`** / **`A`** — hexadecimal floating-point, maps to `hexfloat`

```cpp
fmt::printf("%g", 123456.0);    // → 123456
fmt::printf("%.2g", 123456.0);  // → 1.2e+05
fmt::printf("%a", 3.14159);     // → 0x1.921f9f01b866ep+1

```

## Character, String, and Pointer Specifiers

### Single Character and Strings

- **`c`** — character (integral value converted to character), maps to internal `chr`
- **`s`** — string (C-string or `basic_string_view`), maps to `string`

```cpp
fmt::printf("%c", 65);          // → A
fmt::printf("%s", "hello");     // → hello
fmt::printf("%.3s", "hello");   // → hel

```

### Pointer Address

- **`p`** — pointer address, maps to internal `pointer`

```cpp
int x = 42;
fmt::printf("%p", &x);          // → 0x7ff… (platform-dependent address)

```

## Length Modifiers in fmtlib Format Specifiers

Beyond conversion characters, **fmtlib standard format specifiers** support standard C length modifiers that adapt argument types. These are processed in the `vprintf` function around line 1050 of [`include/fmt/printf.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/printf.h).

| Modifier | Meaning |
|----------|---------|
| `hh` | signed/unsigned `char` |
| `h` | signed/unsigned `short` |
| `l` | `long` / `wchar_t` |
| `ll` | `long long` |
| `j` | `intmax_t` / `uintmax_t` |
| `z` | `size_t` |
| `t` | `ptrdiff_t` |
| `L` | `long double` |

```cpp
fmt::printf("%lld", 9223372036854775807LL);  // long long
fmt::printf("%zu", sizeof(int));              // size_t
fmt::printf("%Lf", 3.14159265358979323846L);  // long double

```

## Source Implementation Details

The **fmtlib format specifier** mapping is implemented in the `parse_printf_presentation_type` function within [`include/fmt/printf.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/printf.h) (around line 86). This function uses a `switch` statement on the conversion character to return the appropriate internal presentation type enum value.

For the modern `{}`-style formatting API, [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) provides the higher-level interface through `fmt::format`, `fmt::print`, and related functions. Both APIs ultimately resolve to the same underlying formatting engine.

The printf-style implementation is header-only; no separate `src/printf.cc` file exists for runtime helpers.

## Summary

- **fmtlib** implements twelve core printf-style format specifiers: `d/i/u`, `o`, `x/X`, `f/F`, `e/E`, `g/G`, `a/A`, `c`, `s`, and `p`
- The `parse_printf_presentation_type` function in [`include/fmt/printf.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/printf.h) (line ~86) maps each specifier to internal presentation types
- Standard C length modifiers (`hh`, `h`, `l`, `ll`, `j`, `z`, `t`, `L`) are fully supported
- Both [`printf.h`](https://github.com/fmtlib/fmt/blob/main/printf.h) and [`format.h`](https://github.com/fmtlib/fmt/blob/main/format.h) provide APIs that resolve to the same formatting engine
- Implementation is header-only with no separate compilation unit required

## Frequently Asked Questions

### What is the difference between %d and %i in fmtlib?

There is no functional difference between `%d` and `%i` in **fmtlib**—both map to the internal `dec` presentation type for signed decimal integers. This matches standard C behavior where both specifiers produce identical output.

### Does fmtlib support the %n specifier for write-back?

No, **fmtlib standard format specifiers** intentionally exclude `%n` due to security considerations. The `{fmt}` documentation notes that this specifier, which writes the number of characters printed back to an argument, is not implemented to prevent format string vulnerabilities.

### How do I print a bool as true/false instead of 1/0 in fmtlib?

Use the modern `{}`-style formatting API from [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) instead of printf-style specifiers. The `fmt::format` function automatically renders `bool` values as `"true"` or `"false"`:

```cpp
fmt::format("{}", true);   // → "true"
fmt::format("{}", false);  // → "false"

```

Printf-style `%d` will print `1` or `0` since `bool` promotes to `int`.

### Can I use fmtlib format specifiers with std::ostream?

Yes, **[`fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/fmt/format.h)** provides `fmt::print` and `fmt::format_to` functions that write to arbitrary output iterators, including `std::ostreambuf_iterator`. For direct `std::ostream` integration, use `fmt::ostream` or the `<fmt/ostream.h>` header which provides automatic `operator<<` integration for fmt-formatted types.