Cheatsheet: Formatação (fmt) em Zig
O módulo std.fmt é responsável por toda a formatação de texto em Zig. Diferente de linguagens com interpolação de string, Zig usa especificadores de formato dentro de strings literais, combinados com tuplas anônimas (.{...}) para os argumentos. Esse sistema é verificado em tempo de compilação — se o formato não bater com os argumentos, o compilador avisa imediatamente.
Funções de Saída
std.debug.print — Debug para stderr
const std = @import("std");
pub fn main() void {
// Saída rápida para stderr (sem try necessário)
std.debug.print("Valor: {d}\n", .{42});
std.debug.print("Nome: {s}, Idade: {d}\n", .{ "Ana", 25 });
}
stdout.print — Saída formatada para stdout
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Olá, {s}!\n", .{"mundo"});
try stdout.print("Resultado: {d:.2}\n", .{3.14159});
// writeAll — sem formatação
try stdout.writeAll("Texto direto sem formato\n");
}
std.log — Sistema de logging
const std = @import("std");
pub fn main() void {
std.log.info("Servidor iniciado na porta {d}", .{8080});
std.log.warn("Cache com {d}% de uso", .{85});
std.log.err("Falha ao conectar: {s}", .{"timeout"});
std.log.debug("Variável x = {d}", .{42});
}
Especificadores de Formato
Tabela de Referência
| Especificador | Tipo | Exemplo | Saída |
|---|---|---|---|
{d} | Inteiro decimal | {d} com 42 | 42 |
{x} | Inteiro hexadecimal minúsculo | {x} com 255 | ff |
{X} | Inteiro hexadecimal maiúsculo | {X} com 255 | FF |
{o} | Inteiro octal | {o} com 8 | 10 |
{b} | Inteiro binário | {b} com 10 | 1010 |
{s} | String/slice de bytes | {s} com "zig" | zig |
{c} | Caractere (u8) | {c} com 65 | A |
{e} | Float em notação científica | {e} com 3.14 | 3.14e0 |
{} | Formato padrão do tipo | {} com 42 | 42 |
{any} | Qualquer tipo (debug) | {any} com struct | representação debug |
Inteiros
const x: i32 = 42;
std.debug.print("Decimal: {d}\n", .{x}); // 42
std.debug.print("Hexadecimal: {x}\n", .{x}); // 2a
std.debug.print("Hex maiúsc.: {X}\n", .{x}); // 2A
std.debug.print("Octal: {o}\n", .{x}); // 52
std.debug.print("Binário: {b}\n", .{x}); // 101010
// Com prefixo
std.debug.print("Hex: 0x{x}\n", .{x}); // 0x2a
std.debug.print("Bin: 0b{b}\n", .{x}); // 0b101010
Floats
const pi: f64 = 3.14159265358979;
std.debug.print("Padrão: {d}\n", .{pi}); // 3.14159265358979
std.debug.print("2 decimais: {d:.2}\n", .{pi}); // 3.14
std.debug.print("5 decimais: {d:.5}\n", .{pi}); // 3.14159
std.debug.print("Científico: {e}\n", .{pi}); // 3.14159e0
Strings
const nome = "Zig Brasil";
std.debug.print("String: {s}\n", .{nome}); // Zig Brasil
Preenchimento e Alinhamento
// Preenchimento com largura mínima
std.debug.print("[{d:>10}]\n", .{42}); // [ 42] — alinhado à direita
std.debug.print("[{d:<10}]\n", .{42}); // [42 ] — alinhado à esquerda
std.debug.print("[{d:^10}]\n", .{42}); // [ 42 ] — centralizado
// Preenchimento com caractere personalizado
std.debug.print("[{d:0>8}]\n", .{42}); // [00000042] — zeros à esquerda
std.debug.print("[{d:_>8}]\n", .{42}); // [______42] — underscores
std.debug.print("[{s:*^20}]\n", .{"ZIG"}); // [********ZIG*********]
// Hex com largura fixa
std.debug.print("0x{x:0>4}\n", .{@as(u16, 10)}); // 0x000a
std.debug.print("0x{X:0>8}\n", .{@as(u32, 255)}); // 0x000000FF
bufPrint — Formatação em Buffer
const std = @import("std");
pub fn main() !void {
var buffer: [256]u8 = undefined;
// Formatar em buffer estático
const resultado = try std.fmt.bufPrint(&buffer, "Nome: {s}, Idade: {d}", .{ "Carlos", 30 });
std.debug.print("Resultado: {s}\n", .{resultado});
std.debug.print("Tamanho: {d}\n", .{resultado.len});
}
allocPrint — Formatação com Alocação
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Formatar com alocação dinâmica
const mensagem = try std.fmt.allocPrint(allocator, "Usuário {s} logou às {d}:{d:0>2}", .{ "admin", 14, 5 });
defer allocator.free(mensagem);
std.debug.print("{s}\n", .{mensagem});
// Saída: "Usuário admin logou às 14:05"
}
comptimePrint — Formatação em comptime
// String formatada em tempo de compilação
const nome_campo = std.fmt.comptimePrint("campo_{d}", .{42});
// nome_campo == "campo_42" (constante comptime)
Formatação Customizada
Você pode implementar a função format em qualquer struct para controlar como ela é exibida:
const std = @import("std");
const Ponto = struct {
x: f32,
y: f32,
pub fn format(
self: Ponto,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;
try writer.print("({d:.1}, {d:.1})", .{ self.x, self.y });
}
};
pub fn main() void {
const p = Ponto{ .x = 3.5, .y = 7.2 };
std.debug.print("Ponto: {}\n", .{p});
// Saída: Ponto: (3.5, 7.2)
}
Formatando Diferentes Tipos
Optionals
const valor: ?i32 = 42;
const nulo: ?i32 = null;
std.debug.print("Valor: {?d}\n", .{valor}); // Valor: 42
std.debug.print("Nulo: {?d}\n", .{nulo}); // Nulo: null
Ponteiros
var x: i32 = 42;
const ptr = &x;
std.debug.print("Endereço: {*}\n", .{ptr}); // Endereço: 0x7fff5a...
std.debug.print("Valor: {d}\n", .{ptr.*}); // Valor: 42
Slices e Arrays
const dados = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
const texto = "Olá";
std.debug.print("Hex: {x}\n", .{std.fmt.fmtSliceHexLower(&dados)});
// Saída: Hex: deadbeef
std.debug.print("Bytes: {s}\n", .{texto});
Enums
const Cor = enum { vermelho, verde, azul };
const c = Cor.verde;
std.debug.print("Cor: {s}\n", .{@tagName(c)}); // Cor: verde
Erros Comuns
// ERRO: Número de argumentos não bate
// std.debug.print("{d} {d}\n", .{42}); // faltou segundo argumento
// ERRO: Especificador errado para o tipo
// std.debug.print("{d}\n", .{"texto"}); // {d} não funciona com string
// ERRO: Esquecer o \n
// std.debug.print("sem newline", .{}); // saída pode não aparecer imediatamente
// CORRETO: Usar {s} para strings, {d} para números
std.debug.print("{s}: {d}\n", .{ "resultado", 42 });
Veja Também
- Strings — Manipulação de strings em Zig
- Operações de I/O — Entrada e saída formatada
- Sintaxe Básica — Print e debug básico
- Builtins — Funções builtin relacionadas a formatação
- std.fmt na Biblioteca Padrão — Documentação completa de std.fmt