std.fmt.parseInt em Zig — Referência e Exemplos

std.fmt.parseInt / parseFloat — Conversão de Strings para Números

As funções std.fmt.parseInt e std.fmt.parseFloat convertem representações textuais de números em valores numéricos tipados. Elas são as equivalentes do atoi/strtol do C e do parseInt/parseFloat do JavaScript, mas com segurança de tipos verificada em tempo de compilação e tratamento explícito de erros.

Visão Geral

const std = @import("std");
const fmt = std.fmt;

Assinaturas

// Converte string para inteiro em qualquer base
pub fn parseInt(comptime T: type, buf: []const u8, base: u8) !T

// Converte string para float
pub fn parseFloat(comptime T: type, buf: []const u8) !T

// Versão unsigned-only
pub fn parseUnsigned(comptime T: type, buf: []const u8, base: u8) !T

Parâmetros

  • T: O tipo numérico de destino (i32, u64, f32, f64, etc.)
  • buf: O slice de bytes contendo a representação textual
  • base: A base numérica (2, 8, 10, 16, ou 0 para detecção automática)

Erros Possíveis

// parseInt pode retornar:
error.InvalidCharacter  // Caractere inválido para a base
error.Overflow          // Valor excede o range do tipo

// parseFloat pode retornar:
error.InvalidCharacter  // Formato inválido

Funções Relacionadas

// Converte inteiro para string
pub fn formatInt(value: anytype, base: u8, case: Case, options: FormatOptions, writer: anytype) !void

// bufPrint para converter número em string
pub fn bufPrint(buf: []u8, comptime format: []const u8, args: anytype) ![]u8

Exemplo 1: Parsing Básico de Inteiros e Floats

const std = @import("std");

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

    // parseInt — base 10
    const idade = try std.fmt.parseInt(u32, "25", 10);
    try stdout.print("Idade: {d}\n", .{idade});

    // parseInt — base 16 (hexadecimal)
    const cor = try std.fmt.parseInt(u24, "FF8000", 16);
    try stdout.print("Cor: 0x{x:0>6}\n", .{cor});

    // parseInt — base 2 (binário)
    const flags = try std.fmt.parseInt(u8, "10110011", 2);
    try stdout.print("Flags: {d} (0b{b:0>8})\n", .{ flags, flags });

    // parseInt — base 0 (detecção automática)
    const auto_dec = try std.fmt.parseInt(i32, "42", 0);
    const auto_hex = try std.fmt.parseInt(i32, "0x2A", 0);
    const auto_bin = try std.fmt.parseInt(i32, "0b101010", 0);
    try stdout.print("Auto: dec={d}, hex={d}, bin={d}\n", .{
        auto_dec, auto_hex, auto_bin,
    }); // Todos são 42

    // parseFloat
    const pi = try std.fmt.parseFloat(f64, "3.14159");
    try stdout.print("Pi: {d:.5}\n", .{pi});

    // Números negativos
    const negativo = try std.fmt.parseInt(i32, "-100", 10);
    try stdout.print("Negativo: {d}\n", .{negativo});

    // Notação científica
    const cientifico = try std.fmt.parseFloat(f64, "6.022e23");
    try stdout.print("Avogadro: {e}\n", .{cientifico});
}

Exemplo 2: Tratamento de Erros na Conversão

const std = @import("std");

fn converterParaInt(texto: []const u8) !i32 {
    return std.fmt.parseInt(i32, texto, 10);
}

fn tentarConverter(texto: []const u8, stdout: anytype) !void {
    if (std.fmt.parseInt(i32, texto, 10)) |valor| {
        try stdout.print("  '{s}' -> {d}\n", .{ texto, valor });
    } else |err| {
        switch (err) {
            error.InvalidCharacter => {
                try stdout.print("  '{s}' -> ERRO: caractere inválido\n", .{texto});
            },
            error.Overflow => {
                try stdout.print("  '{s}' -> ERRO: overflow para i32\n", .{texto});
            },
        }
    }
}

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

    try stdout.writeAll("Conversões de string para i32:\n");

    const testes = [_][]const u8{
        "42",
        "-100",
        "0",
        "abc",
        "12.5",
        "999999999999",
        "",
        "  42",
        "2147483647",
        "2147483648",
    };

    for (testes) |teste| {
        try tentarConverter(teste, stdout);
    }
}

Exemplo 3: Parser de Argumentos Numéricos

const std = @import("std");

const Configuracao = struct {
    porta: u16 = 8080,
    threads: u8 = 4,
    timeout: f64 = 30.0,
    verbose: bool = false,
};

fn parseConfigFromArgs(args: []const []const u8) Configuracao {
    var config = Configuracao{};
    var i: usize = 0;

    while (i < args.len) : (i += 1) {
        const arg = args[i];
        if (std.mem.eql(u8, arg, "--porta") and i + 1 < args.len) {
            i += 1;
            config.porta = std.fmt.parseInt(u16, args[i], 10) catch 8080;
        } else if (std.mem.eql(u8, arg, "--threads") and i + 1 < args.len) {
            i += 1;
            config.threads = std.fmt.parseInt(u8, args[i], 10) catch 4;
        } else if (std.mem.eql(u8, arg, "--timeout") and i + 1 < args.len) {
            i += 1;
            config.timeout = std.fmt.parseFloat(f64, args[i]) catch 30.0;
        } else if (std.mem.eql(u8, arg, "--verbose")) {
            config.verbose = true;
        }
    }

    return config;
}

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

    // Simula argumentos de linha de comando
    const args = [_][]const u8{
        "--porta", "3000",
        "--threads", "8",
        "--timeout", "60.5",
        "--verbose",
    };

    const config = parseConfigFromArgs(&args);

    try stdout.writeAll("Configuração:\n");
    try stdout.print("  Porta:   {d}\n", .{config.porta});
    try stdout.print("  Threads: {d}\n", .{config.threads});
    try stdout.print("  Timeout: {d:.1}s\n", .{config.timeout});
    try stdout.print("  Verbose: {}\n", .{config.verbose});
}

Padrões Comuns

Valor Padrão com catch

const porta = std.fmt.parseInt(u16, texto, 10) catch 8080;

Validação de Range

fn parsePorta(texto: []const u8) !u16 {
    const valor = try std.fmt.parseInt(u16, texto, 10);
    if (valor < 1024) return error.PortaReservada;
    return valor;
}

Conversão de Número para String

var buf: [20]u8 = undefined;
const texto = try std.fmt.bufPrint(&buf, "{d}", .{valor});

Módulos Relacionados

Tutoriais e Receitas Relacionados

Continue aprendendo Zig

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