Como Converter String para Número e Vice-versa em Zig
Converter entre strings e números é uma das tarefas mais comuns em programação. Em Zig, a biblioteca padrão fornece funções robustas para realizar essas conversões com segurança, usando o sistema de tratamento de erros da linguagem.
Nesta receita, você aprenderá a converter strings para inteiros e floats, e também a transformar números de volta para representações textuais.
Converter String para Inteiro
A função std.fmt.parseInt é usada para converter uma string (ou slice de bytes) em um valor inteiro. Ela aceita a base numérica como parâmetro e retorna um erro caso a conversão falhe.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// Converter string decimal para inteiro
const texto_decimal = "42";
const numero = try std.fmt.parseInt(i32, texto_decimal, 10);
try stdout.print("Decimal: \"{s}\" -> {d}\n", .{ texto_decimal, numero });
// Converter string hexadecimal para inteiro
const texto_hex = "FF";
const hex_valor = try std.fmt.parseInt(u32, texto_hex, 16);
try stdout.print("Hexadecimal: \"{s}\" -> {d}\n", .{ texto_hex, hex_valor });
// Converter string binária para inteiro
const texto_bin = "11010";
const bin_valor = try std.fmt.parseInt(u32, texto_bin, 2);
try stdout.print("Binário: \"{s}\" -> {d}\n", .{ texto_bin, bin_valor });
// Converter string octal para inteiro
const texto_oct = "77";
const oct_valor = try std.fmt.parseInt(u32, texto_oct, 8);
try stdout.print("Octal: \"{s}\" -> {d}\n", .{ texto_oct, oct_valor });
// Números negativos
const texto_negativo = "-123";
const negativo = try std.fmt.parseInt(i32, texto_negativo, 10);
try stdout.print("Negativo: \"{s}\" -> {d}\n", .{ texto_negativo, negativo });
}
Saída esperada:
Decimal: "42" -> 42
Hexadecimal: "FF" -> 255
Binário: "11010" -> 26
Octal: "77" -> 63
Negativo: "-123" -> -123
Converter String para Float
Para converter strings em números de ponto flutuante, use std.fmt.parseFloat.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// Converter string para f32
const texto_float = "3.14159";
const pi = try std.fmt.parseFloat(f64, texto_float);
try stdout.print("Float: \"{s}\" -> {d:.5}\n", .{ texto_float, pi });
// Notação científica
const texto_cientifico = "1.5e10";
const cientifico = try std.fmt.parseFloat(f64, texto_cientifico);
try stdout.print("Científico: \"{s}\" -> {d}\n", .{ texto_cientifico, cientifico });
// Número negativo com decimais
const texto_neg = "-273.15";
const negativo = try std.fmt.parseFloat(f64, texto_neg);
try stdout.print("Negativo: \"{s}\" -> {d:.2}\n", .{ texto_neg, negativo });
}
Saída esperada:
Float: "3.14159" -> 3.14159
Científico: "1.5e10" -> 15000000000
Negativo: "-273.15" -> -273.15
Converter Número para String
Para converter números em strings, use std.fmt.bufPrint que escreve a representação formatada em um buffer fornecido por você.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// Converter inteiro para string
var buf: [64]u8 = undefined;
const numero: i32 = 42;
const resultado = try std.fmt.bufPrint(&buf, "{d}", .{numero});
try stdout.print("Inteiro para string: {d} -> \"{s}\"\n", .{ numero, resultado });
// Converter float para string com precisão
var buf2: [64]u8 = undefined;
const pi: f64 = 3.14159265;
const resultado_pi = try std.fmt.bufPrint(&buf2, "{d:.4}", .{pi});
try stdout.print("Float para string: {d:.8} -> \"{s}\"\n", .{ pi, resultado_pi });
// Converter para hexadecimal
var buf3: [64]u8 = undefined;
const valor: u32 = 255;
const hex_str = try std.fmt.bufPrint(&buf3, "{x}", .{valor});
try stdout.print("Hex: {d} -> \"{s}\"\n", .{ valor, hex_str });
// Converter para binário
var buf4: [64]u8 = undefined;
const bin_str = try std.fmt.bufPrint(&buf4, "{b}", .{valor});
try stdout.print("Binário: {d} -> \"{s}\"\n", .{ valor, bin_str });
}
Saída esperada:
Inteiro para string: 42 -> "42"
Float para string: 3.14159265 -> "3.1416"
Hex: 255 -> "ff"
Binário: 255 -> "11111111"
Converter Número para String com Alocador
Quando você precisa de uma string alocada dinamicamente (por exemplo, para retornar de uma função), use std.fmt.allocPrint.
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();
// Criar string formatada alocada dinamicamente
const numero: i32 = 12345;
const texto = try std.fmt.allocPrint(allocator, "O valor é: {d}", .{numero});
defer allocator.free(texto);
try stdout.print("Alocado: \"{s}\"\n", .{texto});
// Formatar múltiplos valores
const x: f64 = 1.5;
const y: f64 = 2.5;
const ponto = try std.fmt.allocPrint(allocator, "({d:.1}, {d:.1})", .{ x, y });
defer allocator.free(ponto);
try stdout.print("Ponto: \"{s}\"\n", .{ponto});
}
Saída esperada:
Alocado: "O valor é: 12345"
Ponto: "(1.5, 2.5)"
Tratando Erros de Conversão
É fundamental tratar os erros que podem ocorrer durante a conversão. A conversão pode falhar se a string contiver caracteres inválidos ou se o valor estiver fora do intervalo do tipo numérico.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// Tentativa com string inválida
const invalido = std.fmt.parseInt(i32, "abc", 10);
if (invalido) |valor| {
try stdout.print("Valor: {d}\n", .{valor});
} else |err| {
try stdout.print("Erro ao converter 'abc': {}\n", .{err});
}
// Overflow: valor muito grande para o tipo
const overflow = std.fmt.parseInt(u8, "300", 10);
if (overflow) |valor| {
try stdout.print("Valor: {d}\n", .{valor});
} else |err| {
try stdout.print("Erro ao converter '300' para u8: {}\n", .{err});
}
// Conversão segura com valor padrão
const texto = "não_é_número";
const valor = std.fmt.parseInt(i32, texto, 10) catch |_| 0;
try stdout.print("Valor com fallback: {d}\n", .{valor});
}
Saída esperada:
Erro ao converter 'abc': error.InvalidCharacter
Erro ao converter '300' para u8: error.Overflow
Valor com fallback: 0
Função Utilitária: Conversão Segura
Aqui está uma função utilitária que encapsula a conversão com um valor padrão.
const std = @import("std");
fn parseIntOuPadrao(comptime T: type, texto: []const u8, padrao: T) T {
return std.fmt.parseInt(T, texto, 10) catch padrao;
}
fn parseFloatOuPadrao(comptime T: type, texto: []const u8, padrao: T) T {
return std.fmt.parseFloat(T, texto) catch padrao;
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const idade = parseIntOuPadrao(u32, "25", 0);
try stdout.print("Idade: {d}\n", .{idade});
const invalido = parseIntOuPadrao(u32, "xyz", 0);
try stdout.print("Inválido com padrão: {d}\n", .{invalido});
const temperatura = parseFloatOuPadrao(f64, "36.6", 0.0);
try stdout.print("Temperatura: {d:.1}\n", .{temperatura});
}
Saída esperada:
Idade: 25
Inválido com padrão: 0
Temperatura: 36.6
Resumo das Funções
| Função | Descrição |
|---|---|
std.fmt.parseInt(T, str, base) | String para inteiro com base especificada |
std.fmt.parseFloat(T, str) | String para ponto flutuante |
std.fmt.bufPrint(&buf, fmt, args) | Número para string em buffer fixo |
std.fmt.allocPrint(alloc, fmt, args) | Número para string alocada dinamicamente |
Veja Também
- Formatar Strings com std.fmt — Aprenda mais sobre formatação de strings
- Converter entre Bases Numéricas — Conversões hex, binário e octal
- Usando GeneralPurposeAllocator — Entenda o alocador usado nos exemplos
- Comparar Strings — Compare strings antes de convertê-las