std.fmt Format Strings em Zig — Referência e Exemplos

std.fmt Format Strings — Sintaxe de Formatação

As format strings do Zig controlam como valores são convertidos em texto. Elas são verificadas em tempo de compilação, garantindo que os tipos dos argumentos correspondam aos especificadores. Este documento detalha toda a sintaxe disponível, incluindo especificadores de tipo, alinhamento, preenchimento e largura.

Visão Geral

Uma format string contém texto literal misturado com campos de substituição delimitados por {}:

"Nome: {s}, Idade: {d} anos"

Cada {} consome o próximo argumento do tuple .{}. Texto literal, incluindo { e }, pode ser escapado com duplicação: {{ produz { literal.

Anatomia de um Especificador

{[argumento][especificador]:[preenchimento][alinhamento][largura][.precisão]}

Cada parte é opcional:

ParteDescriçãoExemplo
especificadorTipo de conversãod, s, x, b
preenchimentoCaractere de padding0, ., -
alinhamentoDireção do alinhamento<, >, ^
larguraLargura mínima10, 20
precisãoCasas decimais ou truncamento.3, .5

Especificadores por Tipo

Inteiros

EspecificadorBaseExemplo (255)
{d}Decimal255
{x}Hex minúsculoff
{X}Hex maiúsculoFF
{o}Octal377
{b}Binário11111111

Floats

EspecificadorFormatoExemplo (3.14159)
{d}Decimal3.14159
{d:.2}2 casas3.14
{e}Científico3.14159e0

Strings e Caracteres

EspecificadorTipoDescrição
{s}[]const u8String
{c}u8Caractere Unicode

Tipos Especiais

EspecificadorDescrição
{}Formato padrão do tipo
{any}Debug — imprime qualquer tipo
{*}Ponteiro como endereço

Exemplo 1: Tabela Formatada com Alinhamento

const std = @import("std");

const Produto = struct {
    nome: []const u8,
    preco: f64,
    estoque: u32,
};

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    const produtos = [_]Produto{
        .{ .nome = "Teclado", .preco = 149.90, .estoque = 42 },
        .{ .nome = "Mouse", .preco = 79.50, .estoque = 108 },
        .{ .nome = "Monitor 27\"", .preco = 1899.00, .estoque = 15 },
        .{ .nome = "Webcam", .preco = 299.90, .estoque = 0 },
    };

    // Cabeçalho
    try stdout.print("{s:<15} {s:>10} {s:>8}\n", .{ "Produto", "Preço", "Estoque" });
    try stdout.print("{s:-<15} {s:->10} {s:->8}\n", .{ "", "", "" });

    // Dados formatados
    for (produtos) |p| {
        const status = if (p.estoque > 0) " " else "!";
        try stdout.print("{s:<15} R${d:>8.2} {d:>7}{s}\n", .{
            p.nome, p.preco, p.estoque, status,
        });
    }
}

Exemplo 2: Formatação de Diferentes Bases Numéricas

const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    try stdout.writeAll("=== Representação de Números ===\n\n");

    const valores = [_]u16{ 0, 10, 42, 127, 255, 1024, 65535 };

    try stdout.print("{s:>6} {s:>8} {s:>6} {s:>18}\n", .{
        "Dec", "Hex", "Oct", "Bin",
    });
    try stdout.print("{s:->6} {s:->8} {s:->6} {s:->18}\n", .{
        "", "", "", "",
    });

    for (valores) |v| {
        try stdout.print("{d:>6} 0x{x:0>4} 0o{o:>5} 0b{b:0>16}\n", .{
            v, v, v, v,
        });
    }

    // Números negativos
    try stdout.writeAll("\nNegativos:\n");
    const neg: i8 = -42;
    try stdout.print("  Decimal: {d}\n", .{neg});
    try stdout.print("  Hex (u8): 0x{x:0>2}\n", .{@as(u8, @bitCast(neg))});
}

Exemplo 3: Format Customizado para Tipos do Usuário

const std = @import("std");

const Duracao = struct {
    segundos_totais: u64,

    pub fn format(
        self: @This(),
        comptime fmt_str: []const u8,
        options: std.fmt.FormatOptions,
        writer: anytype,
    ) !void {
        _ = fmt_str;
        _ = options;
        const horas = self.segundos_totais / 3600;
        const minutos = (self.segundos_totais % 3600) / 60;
        const segundos = self.segundos_totais % 60;
        try writer.print("{d:0>2}:{d:0>2}:{d:0>2}", .{ horas, minutos, segundos });
    }
};

const Endereco = struct {
    ip: [4]u8,
    porta: u16,

    pub fn format(
        self: @This(),
        comptime fmt_str: []const u8,
        options: std.fmt.FormatOptions,
        writer: anytype,
    ) !void {
        _ = fmt_str;
        _ = options;
        try writer.print("{d}.{d}.{d}.{d}:{d}", .{
            self.ip[0], self.ip[1], self.ip[2], self.ip[3], self.porta,
        });
    }
};

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    const duracao = Duracao{ .segundos_totais = 3723 };
    try stdout.print("Duração: {}\n", .{duracao}); // 01:02:03

    const addr = Endereco{ .ip = .{ 192, 168, 1, 100 }, .porta = 8080 };
    try stdout.print("Endereço: {}\n", .{addr}); // 192.168.1.100:8080

    // Arrays e slices
    const dados = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
    try stdout.print("Bytes: {x}\n", .{dados}); // deadbeef
    try stdout.print("Debug: {any}\n", .{dados}); // { 222, 173, 190, 239 }
}

Referência Rápida

// Inteiros
"{d}"            // 42
"{d:>10}"        // "        42"
"{d:0>10}"       // "0000000042"
"{x:0>8}"        // "0000002a"

// Floats
"{d:.2}"         // "3.14"
"{e}"            // "3.14159e0"

// Strings
"{s}"            // "texto"
"{s:.<20}"       // "texto..............."
"{s:^20}"        // "       texto        "

// Escape
"{{"             // literal "{"
"}}"             // literal "}"

Módulos Relacionados

Tutoriais e Receitas Relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.