Como Comparar Strings em Zig
Em Zig, strings são slices de bytes ([]const u8) e não podem ser comparadas diretamente com ==. Em vez disso, a biblioteca padrão fornece funções especializadas para diferentes tipos de comparação.
Comparação de Igualdade com std.mem.eql
A função std.mem.eql compara se dois slices contêm exatamente os mesmos bytes.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const a = "Zig";
const b = "Zig";
const c = "zig";
const d = "Rust";
try stdout.print("\"Zig\" == \"Zig\": {}\n", .{std.mem.eql(u8, a, b)});
try stdout.print("\"Zig\" == \"zig\": {}\n", .{std.mem.eql(u8, a, c)});
try stdout.print("\"Zig\" == \"Rust\": {}\n", .{std.mem.eql(u8, a, d)});
// Comparar com slice vazio
const vazio = "";
try stdout.print("\"\" == \"\": {}\n", .{std.mem.eql(u8, vazio, "")});
try stdout.print("\"Zig\" == \"\": {}\n", .{std.mem.eql(u8, a, "")});
}
Saída esperada:
"Zig" == "Zig": true
"Zig" == "zig": false
"Zig" == "Rust": false
"" == "": true
"Zig" == "": false
Comparação Lexicográfica (Ordenação)
Use std.mem.order para determinar a ordem lexicográfica entre duas strings.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// order retorna .lt, .eq ou .gt
const resultado1 = std.mem.order(u8, "abc", "abd");
try stdout.print("\"abc\" vs \"abd\": {}\n", .{resultado1});
const resultado2 = std.mem.order(u8, "xyz", "xyz");
try stdout.print("\"xyz\" vs \"xyz\": {}\n", .{resultado2});
const resultado3 = std.mem.order(u8, "banana", "abacaxi");
try stdout.print("\"banana\" vs \"abacaxi\": {}\n", .{resultado3});
// Comparações com tamanhos diferentes
const resultado4 = std.mem.order(u8, "abc", "abcd");
try stdout.print("\"abc\" vs \"abcd\": {}\n", .{resultado4});
// Usar para verificar se uma string vem antes de outra
const nome1 = "Maria";
const nome2 = "João";
if (std.mem.order(u8, nome1, nome2) == .gt) {
try stdout.print("\"{s}\" vem depois de \"{s}\"\n", .{ nome1, nome2 });
}
}
Saída esperada:
"abc" vs "abd": math.Order.lt
"xyz" vs "xyz": math.Order.eq
"banana" vs "abacaxi": math.Order.gt
"abc" vs "abcd": math.Order.lt
"Maria" vem depois de "João"
Comparação Case-Insensitive
Para comparar strings ignorando maiúsculas e minúsculas, use std.ascii.eqlIgnoreCase.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// Comparação ignorando caso (case-insensitive)
try stdout.print("\"Zig\" =~ \"zig\": {}\n", .{std.ascii.eqlIgnoreCase("Zig", "zig")});
try stdout.print("\"HELLO\" =~ \"hello\": {}\n", .{std.ascii.eqlIgnoreCase("HELLO", "hello")});
try stdout.print("\"ABC\" =~ \"abd\": {}\n", .{std.ascii.eqlIgnoreCase("ABC", "abd")});
// Exemplo prático: validar comando de usuário
const comando = "SAIR";
if (std.ascii.eqlIgnoreCase(comando, "sair") or
std.ascii.eqlIgnoreCase(comando, "exit") or
std.ascii.eqlIgnoreCase(comando, "quit"))
{
try stdout.print("Comando de saída reconhecido: \"{s}\"\n", .{comando});
}
}
Saída esperada:
"Zig" =~ "zig": true
"HELLO" =~ "hello": true
"ABC" =~ "abd": false
Comando de saída reconhecido: "SAIR"
Verificar Prefixo e Sufixo
Use std.mem.startsWith e std.mem.endsWith para verificar como uma string começa ou termina.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const url = "https://www.exemplo.com.br/pagina";
// Verificar prefixo
try stdout.print("Começa com https: {}\n", .{std.mem.startsWith(u8, url, "https://")});
try stdout.print("Começa com http: {}\n", .{std.mem.startsWith(u8, url, "http://")});
// Verificar sufixo
const arquivo = "relatorio.pdf";
try stdout.print("Termina com .pdf: {}\n", .{std.mem.endsWith(u8, arquivo, ".pdf")});
try stdout.print("Termina com .txt: {}\n", .{std.mem.endsWith(u8, arquivo, ".txt")});
// Exemplo prático: classificar arquivos por extensão
const arquivos = [_][]const u8{ "foto.jpg", "doc.pdf", "video.mp4", "texto.txt", "imagem.png" };
try stdout.print("\nArquivos de imagem:\n", .{});
for (arquivos) |arq| {
if (std.mem.endsWith(u8, arq, ".jpg") or
std.mem.endsWith(u8, arq, ".png"))
{
try stdout.print(" {s}\n", .{arq});
}
}
}
Saída esperada:
Começa com https: true
Começa com http: false
Termina com .pdf: true
Termina com .txt: false
Arquivos de imagem:
foto.jpg
imagem.png
Comparação Personalizada para Ordenação
Crie funções de comparação personalizadas para usar com std.mem.sort.
const std = @import("std");
fn compararStringsIgnorandoCaso(_: void, a: []const u8, b: []const u8) bool {
// Retorna true se a < b (ignorando caso)
for (a, 0..) |char_a, i| {
if (i >= b.len) return false;
const lower_a = std.ascii.toLower(char_a);
const lower_b = std.ascii.toLower(b[i]);
if (lower_a < lower_b) return true;
if (lower_a > lower_b) return false;
}
return a.len < b.len;
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// Ordenar strings ignorando caso
var nomes = [_][]const u8{ "carlos", "Ana", "beatriz", "Daniel", "alice" };
std.mem.sort([]const u8, &nomes, {}, compararStringsIgnorandoCaso);
try stdout.print("Nomes ordenados (case-insensitive):\n", .{});
for (nomes) |nome| {
try stdout.print(" {s}\n", .{nome});
}
}
Saída esperada:
Nomes ordenados (case-insensitive):
alice
Ana
beatriz
carlos
Daniel
Verificar se String Contém Outra
Use std.mem.indexOf para verificar se uma string contém outra (mais detalhes na receita de busca de substrings).
const std = @import("std");
fn contem(haystack: []const u8, needle: []const u8) bool {
return std.mem.indexOf(u8, haystack, needle) != null;
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const texto = "A linguagem Zig é eficiente e segura";
try stdout.print("Contém \"Zig\": {}\n", .{contem(texto, "Zig")});
try stdout.print("Contém \"Rust\": {}\n", .{contem(texto, "Rust")});
try stdout.print("Contém \"eficiente\": {}\n", .{contem(texto, "eficiente")});
}
Saída esperada:
Contém "Zig": true
Contém "Rust": false
Contém "eficiente": true
Resumo das Funções
| Função | Descrição |
|---|---|
std.mem.eql(u8, a, b) | Igualdade exata |
std.mem.order(u8, a, b) | Ordenação lexicográfica |
std.ascii.eqlIgnoreCase(a, b) | Igualdade case-insensitive |
std.mem.startsWith(u8, str, prefix) | Verifica prefixo |
std.mem.endsWith(u8, str, suffix) | Verifica sufixo |
std.mem.indexOf(u8, hay, needle) | Verifica se contém |
Veja Também
- Buscar Substrings — Pesquisa avançada em strings
- Converter Maiúsculas e Minúsculas — Normalize antes de comparar
- Ordenar Arrays e Slices — Ordene coleções de strings
- Dividir (Split) Strings — Divida antes de comparar