Como Formatar Strings com std.fmt em Zig
O sistema de formatação de Zig (std.fmt) é poderoso e seguro em tempo de compilação. Diferente de printf em C, o compilador verifica os tipos dos argumentos e detecta erros antes da execução.
Especificadores Básicos de Formato
Cada especificador começa com { e termina com }. O tipo do argumento determina qual especificador usar.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// {d} - inteiros decimais
try stdout.print("Inteiro: {d}\n", .{42});
// {s} - strings (slices de u8)
try stdout.print("String: {s}\n", .{"Olá Zig"});
// {c} - caractere único (u8)
try stdout.print("Caractere: {c}\n", .{'A'});
// {x} - hexadecimal minúsculo
try stdout.print("Hex: {x}\n", .{@as(u32, 255)});
// {X} - hexadecimal maiúsculo
try stdout.print("HEX: {X}\n", .{@as(u32, 255)});
// {o} - octal
try stdout.print("Octal: {o}\n", .{@as(u32, 255)});
// {b} - binário
try stdout.print("Binário: {b}\n", .{@as(u8, 42)});
// {e} - notação científica
try stdout.print("Científico: {e}\n", .{@as(f64, 12345.6789)});
// {} - formato padrão (baseado no tipo)
try stdout.print("Padrão: {}\n", .{@as(u32, 42)});
// {any} - formato para qualquer tipo (debug)
const ponto = .{ .x = 10, .y = 20 };
try stdout.print("Debug: {any}\n", .{ponto});
}
Saída esperada:
Inteiro: 42
String: Olá Zig
Caractere: A
Hex: ff
HEX: FF
Octal: 377
Binário: 101010
Científico: 1.23456789e4
Padrão: 42
Debug: .{ .x = 10, .y = 20 }
Formatação de Números com Precisão
Controle casas decimais e largura de campo para números.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const pi: f64 = 3.14159265358979;
// Precisão de casas decimais
try stdout.print("2 casas: {d:.2}\n", .{pi});
try stdout.print("4 casas: {d:.4}\n", .{pi});
try stdout.print("8 casas: {d:.8}\n", .{pi});
// Valores monetários
const preco: f64 = 1299.90;
try stdout.print("Preço: R$ {d:.2}\n", .{preco});
// Porcentagem
const taxa: f64 = 0.1575;
try stdout.print("Taxa: {d:.2}%\n", .{taxa * 100.0});
}
Saída esperada:
2 casas: 3.14
4 casas: 3.1416
8 casas: 3.14159265
Preço: R$ 1299.90
Taxa: 15.75%
Largura de Campo e Alinhamento
Defina a largura mínima e o alinhamento do texto formatado.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// Largura mínima com alinhamento à direita (padrão para números)
try stdout.print("|{d:10}|\n", .{@as(i32, 42)});
try stdout.print("|{d:10}|\n", .{@as(i32, 12345)});
// Alinhamento à esquerda com <
try stdout.print("|{s:<10}| esquerda\n", .{"abc"});
// Alinhamento à direita com >
try stdout.print("|{s:>10}| direita\n", .{"abc"});
// Alinhamento centralizado com ^
try stdout.print("|{s:^10}| centro\n", .{"abc"});
// Preenchimento com caractere personalizado
try stdout.print("|{s:-<10}|\n", .{"abc"});
try stdout.print("|{s:->10}|\n", .{"abc"});
try stdout.print("|{s:-^10}|\n", .{"abc"});
// Preenchimento com zeros para números
try stdout.print("Com zeros: {d:0>8}\n", .{@as(u32, 42)});
}
Saída esperada:
| 42|
| 12345|
|abc | esquerda
| abc| direita
| abc | centro
|abc-------|
|-------abc|
|---abc----|
Com zeros: 00000042
Formatação em Buffer Fixo
Use std.fmt.bufPrint para formatar em um buffer sem alocação dinâmica.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
var buf: [256]u8 = undefined;
// Formatar em buffer
const msg = try std.fmt.bufPrint(&buf, "Olá, {s}! Você tem {d} mensagens.", .{ "Maria", @as(u32, 5) });
try stdout.print("{s}\n", .{msg});
// Formatar data
const data = try std.fmt.bufPrint(&buf, "{d:0>2}/{d:0>2}/{d}", .{ @as(u32, 21), @as(u32, 2), @as(u32, 2026) });
try stdout.print("Data: {s}\n", .{data});
// Formatar endereço IP
const ip = try std.fmt.bufPrint(&buf, "{d}.{d}.{d}.{d}", .{ @as(u8, 192), @as(u8, 168), @as(u8, 1), @as(u8, 100) });
try stdout.print("IP: {s}\n", .{ip});
}
Saída esperada:
Olá, Maria! Você tem 5 mensagens.
Data: 21/02/2026
IP: 192.168.1.100
Formatação com Alocação Dinâmica
Use std.fmt.allocPrint quando precisar de strings alocadas dinamicamente.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Formatar com alocação
const nome = "Zig Brasil";
const membros: u32 = 1500;
const texto = try std.fmt.allocPrint(allocator, "Comunidade {s} com {d} membros", .{ nome, membros });
defer allocator.free(texto);
try stdout.print("{s}\n", .{texto});
// Construir JSON simples
const json = try std.fmt.allocPrint(
allocator,
"{{\"nome\": \"{s}\", \"idade\": {d}, \"ativo\": true}}",
.{ "Carlos", @as(u32, 30) },
);
defer allocator.free(json);
try stdout.print("JSON: {s}\n", .{json});
}
Saída esperada:
Comunidade Zig Brasil com 1500 membros
JSON: {"nome": "Carlos", "idade": 30, "ativo": true}
Implementar Formatação Personalizada
Você pode implementar a função format para seus próprios tipos.
const std = @import("std");
const Ponto = struct {
x: f64,
y: f64,
pub fn format(
self: Ponto,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;
try writer.print("({d:.2}, {d:.2})", .{ self.x, self.y });
}
};
const Cor = struct {
r: u8,
g: u8,
b: u8,
pub fn format(
self: Cor,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;
try writer.print("#{X:0>2}{X:0>2}{X:0>2}", .{ self.r, self.g, self.b });
}
};
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const p = Ponto{ .x = 3.14159, .y = 2.71828 };
try stdout.print("Ponto: {}\n", .{p});
const cor = Cor{ .r = 255, .g = 128, .b = 0 };
try stdout.print("Cor: {}\n", .{cor});
}
Saída esperada:
Ponto: (3.14, 2.72)
Cor: #FF8000
Tabela de Especificadores
| Especificador | Tipo | Descrição |
|---|---|---|
{d} | Inteiros | Decimal |
{x} / {X} | Inteiros | Hexadecimal minúsculo/maiúsculo |
{o} | Inteiros | Octal |
{b} | Inteiros | Binário |
{s} | []const u8 | String |
{c} | u8 | Caractere |
{e} | Floats | Notação científica |
{any} | Qualquer | Representação de debug |
{} | Qualquer | Formato padrão do tipo |
Veja Também
- Converter String para Número — Parse de strings formatadas
- Concatenar Strings — Junte strings com formatação
- Converter entre Bases Numéricas — Formatação em hex, bin, oct
- Escrever em Arquivo — Use formatação ao escrever em arquivos