std::wstring vs std::string: o que escolher para Unicode?

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: duas strings, uma dor de cabeça

\n\n

Todo desenvolvedor C++ mais cedo ou mais tarde enfrenta o dilema: std::string ou std::wstring? Aparentemente ambos são strings, ambos da STL, mas se comportam de maneiras completamente diferentes. Esta questão se torna especialmente crítica ao trabalhar com texto multilíngue, emojis ou ideogramas.

\n\n

Se você programa em C++ e quer que seu programa processe corretamente "Olá, mundo!" em russo, japonês ou árabe — não há como evitar entender a diferença entre std::string e std::wstring. Neste artigo, analisaremos ambas as abordagens, compararemos seus principais parâmetros e decidiremos quando usar cada uma.

\n\n
Este material é baseado em uma pergunta real do Stack Overflow, que acumulou milhares de visualizações. Nós o adaptamos para fins educacionais, adicionando exemplos e uma estrutura clara.
\n\n

std::string: clássico e simples

\n\n

std::string é um apelido para std::basic_string<char>. Cada caractere ocupa 1 byte. Historicamente, char era usado para caracteres ASCII, mas hoje em dia geralmente armazena dados na codificação UTF-8 (ou apenas bytes).

\n\n

Vantagens do std::string

\n
    \n
  • Economia de memória — 1 byte por caractere para ASCII/UTF-8.
  • \n
  • Compatibilidade — funciona com a maioria das bibliotecas, incluindo funções C (strlen, strcpy).
  • \n
  • Velocidade — menos sobrecarga de alocação.
  • \n
  • Onipresença — padrão de facto para transmissão de dados pela rede e em JSON.
  • \n
\n\n

Desvantagens do std::string

\n
    \n
  • Confusão com codificações — std::string não sabe em qual codificação os dados estão armazenados. Você pode armazenar UTF-8 nele, mas .size() retornará o número de bytes, não de caracteres.
  • \n
  • Problemas com Unicode — a iteração pela string pode quebrar um caractere multibyte.
  • \n
  • Sem suporte nativo para caracteres largos — para trabalhar com Unicode fora do UTF-8, você precisará de bibliotecas de terceiros.
  • \n
\n\n
// Exemplo: std::string com UTF-8\n#include <iostream>\n#include <string>\n\nint main() {\n    std::string s = "Привет, мир!";\n    std::cout << "Comprimento em bytes: " << s.size() << std::endl; // 21 bytes\n    std::cout << "Primeiro caractere (como char): " << s[0] << std::endl; // Lixo: primeiro byte do UTF-8\n    return 0;\n}
\n\n

Neste exemplo, s[0] retornará não 'П', mas o primeiro byte do caractere de dois bytes 'П' (0xD0). Este é um erro comum de iniciantes.

\n\n

std::wstring: o poder dos caracteres largos

\n\n

std::wstring é std::basic_string<wchar_t>. O tamanho de wchar_t depende da plataforma: 2 bytes no Windows (UTF-16) e 4 bytes no Linux/macOS (UTF-32).

\n\n

Vantagens do std::wstring

\n
    \n
  • Tamanho fixo do caractere (em uma plataforma específica) — simplifica o trabalho com Unicode.
  • \n
  • Suporte direto a locales — no Windows, todas as funções WinAPI trabalham com wchar_t.
  • \n
  • Menos problemas com caracteres multibyte — cada caractere é um elemento da string.
  • \n
\n\n

Desvantagens do std::wstring

\n
    \n
  • Tamanho depende da plataforma — o código pode se comportar de forma diferente no Windows e no Linux.
  • \n
  • Maior consumo de memória — 2 ou 4 bytes por caractere, mesmo para ASCII.
  • \n
  • Problemas de compatibilidade — nem todas as bibliotecas suportam wchar_t.
  • \n
  • Pares substitutos — em UTF-16, alguns caracteres (por exemplo, emojis) ocupam 2 wchar_t, o que novamente cria o problema de "caractere ≠ elemento".
  • \n
\n\n
// Exemplo: std::wstring no Windows\n#include <iostream>                

Blogs

Book Recommendations