---
title: "Cheatsheet: Strings em Zig"
url: "https://ziglang.com.br/cheatsheets/cheatsheet-strings-em-zig/"
markdown_url: "https://ziglang.com.br/cheatsheets/cheatsheet-strings-em-zig.MD"
description: "Referência rápida para manipulação de strings em Zig: slices de bytes, concatenação, busca, formatação e conversões. Guia completo em português."
date: "2026-02-21"
author: "Zig Brasil"
---

# Cheatsheet: Strings em Zig

Referência rápida para manipulação de strings em Zig: slices de bytes, concatenação, busca, formatação e conversões. Guia completo em português.


# Cheatsheet: Strings em Zig

Em Zig, strings são simplesmente **slices de bytes** (`[]const u8`). Não existe um tipo `String` especial. Esta cheatsheet cobre todas as operações comuns com strings.

## Tipos de String

```zig
// String literal — array de bytes com sentinela null
const literal: *const [5:0]u8 = "Hello";

// Slice de string (mais comum)
const slice: []const u8 = "Hello";

// String mutável
var buffer: [100]u8 = undefined;
var str: []u8 = buffer[0..5];

// String com sentinela (compatível com C)
const c_str: [*:0]const u8 = "Hello";
const sentinel_slice: [:0]const u8 = "Hello";
```

## Comparação de Strings

```zig
const std = @import("std");

const a = "hello";
const b = "hello";
const c = "world";

// Comparar igualdade
const iguais = std.mem.eql(u8, a, b);     // true
const diferentes = std.mem.eql(u8, a, c);  // false

// Comparação ordenada
const ordem = std.mem.order(u8, a, c);  // .lt, .eq ou .gt
const menor = std.mem.lessThan(u8, a, c);  // true ("hello" < "world")
```

## Busca em Strings

```zig
const texto = "Hello, World! Hello, Zig!";

// Encontrar substring
const pos = std.mem.indexOf(u8, texto, "World");  // ?usize = 7
const ultima = std.mem.lastIndexOf(u8, texto, "Hello");  // ?usize = 14

// Encontrar caractere
const virgula = std.mem.indexOfScalar(u8, texto, ',');  // ?usize = 5

// Verificar prefixo e sufixo
const comeca = std.mem.startsWith(u8, texto, "Hello");  // true
const termina = std.mem.endsWith(u8, texto, "Zig!");    // true

// Contar ocorrências
const count = std.mem.count(u8, texto, "Hello");  // 2

// Verificar se contém
const contem = std.mem.indexOf(u8, texto, "World") != null;  // true
```

## Fatiamento (Slicing)

```zig
const texto = "Hello, World!";

const hello = texto[0..5];     // "Hello"
const world = texto[7..12];    // "World"
const resto = texto[7..];      // "World!"

// Obter último caractere
const ultimo = texto[texto.len - 1];  // '!'

// Iterar sobre caracteres
for (texto) |byte| {
    std.debug.print("{c}", .{byte});
}

// Iterar com índice
for (texto, 0..) |byte, i| {
    std.debug.print("[{}]={c} ", .{ i, byte });
}
```

## Divisão (Split)

```zig
const std = @import("std");

const csv = "nome,idade,cidade";

// Split por delimitador
var it = std.mem.splitSequence(u8, csv, ",");
while (it.next()) |campo| {
    std.debug.print("Campo: {s}\n", .{campo});
}
// Saída: "nome", "idade", "cidade"

// Split por caractere único
const path = "/usr/local/bin";
var it2 = std.mem.splitScalar(u8, path, '/');
while (it2.next()) |parte| {
    if (parte.len > 0) {
        std.debug.print("Parte: {s}\n", .{parte});
    }
}

// Tokenize (ignora delimitadores consecutivos)
const texto = "  hello   world  ";
var tok = std.mem.tokenizeScalar(u8, texto, ' ');
while (tok.next()) |token| {
    std.debug.print("Token: '{s}'\n", .{token});
}
// Saída: "hello", "world"
```

## Concatenação

```zig
const std = @import("std");

// Em comptime (concatenação de literais)
const saudacao = "Olá, " ++ "mundo!";  // "Olá, mundo!"

// Repetição em comptime
const tracos = "-" ** 20;  // "--------------------"

// Em runtime com allocator
const allocator = std.heap.page_allocator;
const resultado = try std.mem.concat(allocator, u8, &.{ "Hello", " ", "World" });
defer allocator.free(resultado);

// Com std.fmt.allocPrint
const nome = "Zig";
const msg = try std.fmt.allocPrint(allocator, "Olá, {s}! Versão {d}", .{ nome, 13 });
defer allocator.free(msg);
```

## Formatação

```zig
const std = @import("std");

// Formatar em buffer fixo
var buf: [256]u8 = undefined;
const resultado = try std.fmt.bufPrint(&buf, "Valor: {d}, Hex: 0x{x}", .{ 42, 255 });
// resultado é []u8 contendo "Valor: 42, Hex: 0xff"

// Especificadores comuns
// {s}     — string ([]const u8)
// {d}     — decimal
// {x}     — hexadecimal minúsculo
// {X}     — hexadecimal maiúsculo
// {b}     — binário
// {o}     — octal
// {e}     — notação científica
// {c}     — caractere (u8)
// {any}   — qualquer tipo (debug)
// {}      — formato padrão

// Preenchimento e alinhamento
const alinhado = try std.fmt.bufPrint(&buf, "|{s:>10}|", .{"zig"});
// "|       zig|"

const esquerda = try std.fmt.bufPrint(&buf, "|{s:<10}|", .{"zig"});
// "|zig       |"

const centro = try std.fmt.bufPrint(&buf, "|{s:^10}|", .{"zig"});
// "|   zig    |"

// Zeros à esquerda
const zeros = try std.fmt.bufPrint(&buf, "{d:0>5}", .{42});
// "00042"
```

## Trim (Remover Espaços)

```zig
const std = @import("std");

const texto = "  Hello, World!  ";

// Trim ambos os lados
const trimmed = std.mem.trim(u8, texto, " ");  // "Hello, World!"

// Trim à esquerda
const ltrimmed = std.mem.trimLeft(u8, texto, " ");  // "Hello, World!  "

// Trim à direita
const rtrimmed = std.mem.trimRight(u8, texto, " ");  // "  Hello, World!"

// Trim de múltiplos caracteres
const dados = "\n\t  dados  \n\t";
const limpo = std.mem.trim(u8, dados, &[_]u8{ ' ', '\n', '\t' });  // "dados"
```

## Substituição

```zig
const std = @import("std");
const allocator = std.heap.page_allocator;

const texto = "Hello World Hello Zig";

// Substituir todas as ocorrências
const resultado = try std.mem.replaceOwned(u8, allocator, texto, "Hello", "Olá");
defer allocator.free(resultado);
// "Olá World Olá Zig"
```

## Conversão Maiúsculas/Minúsculas

```zig
const std = @import("std");

const texto = "Hello World";
var buf: [100]u8 = undefined;

// Para minúsculas
const lower = std.ascii.lowerString(buf[0..texto.len], texto);
// "hello world"

// Para maiúsculas
const upper = std.ascii.upperString(buf[0..texto.len], texto);
// "HELLO WORLD"

// Verificar se caractere é letra, dígito, etc.
const eh_alpha = std.ascii.isAlphabetic('A');  // true
const eh_digit = std.ascii.isDigit('5');       // true
const eh_space = std.ascii.isWhitespace(' ');  // true
```

## Conversão Número ↔ String

```zig
const std = @import("std");

// String → Inteiro
const num = try std.fmt.parseInt(i32, "42", 10);    // 42
const hex = try std.fmt.parseInt(u32, "FF", 16);     // 255
const bin = try std.fmt.parseInt(u8, "1010", 2);     // 10

// String → Float
const pi = try std.fmt.parseFloat(f64, "3.14159");  // 3.14159

// Inteiro → String
var buf: [20]u8 = undefined;
const str = try std.fmt.bufPrint(&buf, "{d}", .{42});  // "42"
```

## ArrayList como String Builder

```zig
const std = @import("std");

pub fn construirString(allocator: std.mem.Allocator) ![]u8 {
    var lista = std.ArrayList(u8).init(allocator);
    defer lista.deinit();

    try lista.appendSlice("Olá");
    try lista.appendSlice(", ");
    try lista.appendSlice("mundo!");
    try lista.append('!');

    // Transferir propriedade para o chamador
    return lista.toOwnedSlice();
}
```

## UTF-8

```zig
const std = @import("std");

const texto = "Olá, São Paulo!";

// Zig trata strings como bytes UTF-8
// Para iterar sobre code points Unicode:
var view = std.unicode.Utf8View.initUnchecked(texto);
var it = view.iterator();
while (it.nextCodepoint()) |cp| {
    std.debug.print("U+{X:0>4}\n", .{cp});
}

// Validar UTF-8
const valido = std.unicode.utf8ValidateSlice(texto);  // true

// Comprimento em code points (não em bytes)
const byte_len = texto.len;  // número de bytes
var cp_len: usize = 0;
var iter = std.unicode.Utf8View.initUnchecked(texto).iterator();
while (iter.nextCodepoint()) |_| {
    cp_len += 1;
}
```

## Tabela de Referência Rápida

| Operação | Função |
|----------|--------|
| Comparar | `std.mem.eql(u8, a, b)` |
| Buscar substring | `std.mem.indexOf(u8, str, sub)` |
| Começa com | `std.mem.startsWith(u8, str, prefix)` |
| Termina com | `std.mem.endsWith(u8, str, suffix)` |
| Dividir | `std.mem.splitSequence(u8, str, delim)` |
| Trim | `std.mem.trim(u8, str, chars)` |
| Concatenar | `std.mem.concat(alloc, u8, slices)` |
| Formatar | `std.fmt.bufPrint(&buf, fmt, args)` |
| Parse int | `std.fmt.parseInt(T, str, base)` |
| Parse float | `std.fmt.parseFloat(T, str)` |
| Minúsculas | `std.ascii.lowerString(buf, str)` |

A manipulação de strings em Zig é explícita e baseada em slices de bytes, diferente de linguagens com tipos string nativos. Para comparação, veja como <a href="https://golang.com.br/artigos/go-strings/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">Go lida com strings como slices imutáveis de bytes</a> e como <a href="https://rustlang.com.br/artigos/rust-strings/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust distingue entre String e &amp;str com ownership</a>.

## Veja Também

- [Sintaxe Básica](/cheatsheets/sintaxe-basica/) — Literais de string
- [Arrays e Slices](/cheatsheets/arrays-slices/) — Operações com arrays
- [Formatação](/cheatsheets/fmt-formatacao/) — Especificadores de formato detalhados
- [I/O](/cheatsheets/io-operacoes/) — Leitura e escrita de texto
- [Interop com C](/cheatsheets/c-interop/) — Strings terminadas em null
