# Formatting

> Format strings checked at compile time.

```zig
const std = @import("std");
const expect = std.testing.expect;

test "bufPrint formats into memory you own" {
    var buf: [64]u8 = undefined;
    const text = try std.fmt.bufPrint(&buf, "{s} is {d}", .{ "answer", 42 });
    try expect(std.mem.eql(u8, text, "answer is 42"));
}

test "common specifiers" {
    var buf: [64]u8 = undefined;

    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{d}", .{255}), "255"));
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{x}", .{255}), "ff"));
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{X}", .{255}), "FF"));
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{b}", .{5}), "101"));
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{o}", .{8}), "10"));
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{c}", .{@as(u8, 'A')}), "A"));
}

test "width, alignment and fill" {
    var buf: [64]u8 = undefined;

    // {[fill][align][width]}: align is <, ^ or >.
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{d:5}", .{42}), "   42"));
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{d:<5}", .{42}), "42   "));
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{d:^5}", .{42}), " 42  "));
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{d:0>5}", .{42}), "00042"));
}

test "float precision" {
    var buf: [64]u8 = undefined;
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{d:.2}", .{3.14159}), "3.14"));
}

test "escaping braces" {
    var buf: [64]u8 = undefined;
    try expect(std.mem.eql(u8, try std.fmt.bufPrint(&buf, "{{{d}}}", .{1}), "{1}"));
}

test "allocPrint when the length is unknown" {
    const gpa = std.testing.allocator;
    const text = try std.fmt.allocPrint(gpa, "{d}-{d}", .{ 1, 2 });
    defer gpa.free(text);
    try expect(std.mem.eql(u8, text, "1-2"));
}
```

*Runnable: compiled to WebAssembly and executed by CI against Zig master. (`03-standard-library.formatting`)*

## Where the output goes

| Function | Writes to |
| --- | --- |
| `bufPrint` | a buffer you supply (no allocation) |
| `allocPrint` | fresh memory (caller frees) |
| `writer.print` | any writer |

`bufPrint` returns a slice of the part it filled, and fails with
`error.NoSpaceLeft` rather than truncating.

## Specifiers

| Spec | Meaning |
| --- | --- |
| `{d}` | decimal |
| `{x}` / `{X}` | lower / upper hex |
| `{b}` / `{o}` | binary / octal |
| `{s}` | string |
| `{c}` | a byte as a character |
| `{any}` | structural dump |

## Width, alignment, precision

The form is `{[fill][align][width]}`, with `<` `^` `>` for alignment:

```zig
"{d:5}"     // "   42"  (right by default for numbers)
"{d:<5}"    // "42   "
"{d:^5}"    // " 42  "
"{d:0>5}"   // "00042"
"{d:.2}"    // "3.14"
```

Escape a literal brace by doubling it: `{{` and `}}`.

## Checked at compile time

The format string is a comptime parameter, so the argument count and each
specifier are validated against the argument types during compilation. A `{d}`
pointed at a string does not compile. There is no runtime format-string
failure mode to worry about.
