Skip to main content

Contagem de caracteres | CSharp

  • Contagem de caracteres | CSharp
info

Cada letra pode ser representado por um número (varia de acordo com as tabelas de codificaçäo) e cada número representa uma sequência de bits

  • O processo de converter de texto -> número -> bits chama se encoding e o processo reverso chama-se decoding

Tabelas de codificação | ASCII e Unicode

🧮 1. Tabela ASCII

📖 O que é

ASCII (American Standard Code for Information Interchange) é o padrão mais antigo de codificação de caracteres — criado nos anos 1960. Ele define 128 símbolos básicos (números de 0 a 127), cada um associado a um caractere.

🔢 Estrutura

  • Cada caractere é representado por 1 byte (8 bits), mas apenas 7 bits são usados (o 8º era reservado para controle).

  • Exemplo:

    DecimalHexCaractereDescrição
    650x41ALetra maiúscula A
    970x61aLetra minúscula a
    480x300Dígito zero
    320x20 Espaço
    100x0A\nQuebra de linha

⚙️ Limitação

  • Representa apenas o alfabeto inglês, dígitos e alguns símbolos básicos.
  • Não suporta acentos (é, ç, ñ, etc.) nem caracteres de outros idiomas.

👉 Por isso surgiram extensões como ISO-8859-1 (Latin-1) e, mais tarde, o Unicode.


🌍 2. Tabela Unicode

📖 O que é

Unicode é o padrão moderno e universal que busca representar todos os caracteres de todas as línguas, símbolos matemáticos, emojis, etc. Cada caractere recebe um código numérico único, chamado code point.

  • Intervalo total: U+0000 até U+10FFFF (mais de 1 milhão de posições possíveis)
  • Atualmente cobre mais de 149.000 caracteres (letras, ideogramas, símbolos, emojis...)

🔢 Exemplo de mapeamento

CaractereNomeCode Point (Unicode)
ALatin Capital Letter AU+0041
éLatin Small Letter e with acuteU+00E9
Chinese character “zhong”U+4E2D
😀Grinning Face EmojiU+1F600

💾 Unicode não é uma codificação

Unicode é uma tabela de referência — uma lista de todos os símbolos e seus números (code points).

Para armazenar/transmitir esses números em bytes, usamos codificações Unicode, como:

  • UTF-8
  • UTF-16
  • UTF-32

🔗 3. Relação entre ASCII e Unicode

  • Os 128 primeiros caracteres de Unicode (U+0000 a U+007F) são idênticos ao ASCII.
  • Isso garante retrocompatibilidade — qualquer texto ASCII é automaticamente válido em Unicode.
ASCIIUnicodeCaractere
65U+0041A
97U+0061a
32U+0020espaço
10U+000Anova linha

Resumo rápido

PropriedadeASCIIUnicode
Criado em19631991
Capacidade128 símbolos+1.1 milhão de símbolos possíveis
Tamanho por caractere1 byte (7 bits usados)variável (1–4 bytes)
Suporte a idiomasApenas inglêsTodos os idiomas do mundo
Compatível com Unicode?Sim (Unicode inclui ASCII)

Dentro do C#

info

Bytes

  • Um byte é composto por 8 bits — essa é uma convenção universal adotada na computação moderna.
  • Um bit (binary digit) é a menor unidade de informação: Pode ter apenas dois valores → 0 ou 1.

Exemplo:

1 bit → 0 ou 1
  • Um byte é formado por 8 bits.
  • Ele pode representar 256 valores diferentes (2⁸ = 256). → De 0 a 255 em decimal, → Ou 00 a FF em hexadecimal.

Exemplo:

1 byte = 8 bits = 01000001 = 65 decimal = letra 'A' em ASCII

🔤 1. C# usa UTF-16 internamente

Em C#, uma string é uma sequência de char, e cada char tem 16 bits (2 bytes). Ou seja, o C# representa strings em UTF-16.

Exemplo simples:

string texto = "ABC";
Console.WriteLine(texto.Length); // 3

✅ Cada caractere (A, B, C) cabe em 1 char. Portanto, Length = 3.


🧩 2. Emojis e caracteres “grandes” ocupam 2 chars

Alguns caracteres (como emojis ou letras raras) estão fora do BMP (Basic Multilingual Plane). Eles exigem 2 unidades UTF-16 — chamadas pares substitutos (surrogate pairs).

string emoji = "😀"; // U+1F600
Console.WriteLine(emoji.Length); // 2

➡️ Mesmo sendo um único símbolo visível, ele ocupa 2 chars internamente. Cada char contém metade do emoji (\uD83D e \uDE00).


📏 3. Comparando Length, Rune e StringInfo

Vamos comparar três formas de contagem no C# moderno (.NET 5+):

using System;
using System.Globalization;
using System.Linq;
using System.Text;

class Program
{
static void Main()
{
string texto = "A😀👩‍❤️‍💋‍👩";

Console.WriteLine($"String: {texto}");
Console.WriteLine($"Length (chars): {texto.Length}");

// 1️⃣ Contando code points (Rune)
int codePoints = texto.EnumerateRunes().Count();
Console.WriteLine($"Code points: {codePoints}");

// 2️⃣ Contando elementos visuais (grapheme clusters)
int textElements = new StringInfo(texto).LengthInTextElements;
Console.WriteLine($"Text elements (visuais): {textElements}");
}
}

Saída:

String: String: A😀👩❤️💋👩
Length (chars): 11
Code points: 7
Text elements (visuais): 6

String no console: alt text

Explicando:

Tipo de contagemO que medeValor
LengthUnidades UTF-16 (chars)11
EnumerateRunes()Pontos de código Unicode7
StringInfo.LengthInTextElementsElementos visuais que o usuário vê6

👉 O usuário vê 3 símbolos: “A”, “😀”, e “👩‍❤️‍💋‍👩”, mas internamente há muitos code units para representar cada um.


🔍 4. Quando usar cada um

MétodoUso indicado
texto.LengthQuando só importa o número de chars (UTF-16) — ex: manipulação interna
texto.EnumerateRunes().Count()Quando você quer contar code points Unicode (cada símbolo atômico)
new StringInfo(texto).LengthInTextElementsQuando você quer contar caracteres visuais (o que o usuário enxerga)

🧠 5. Visualizando internamente

Você pode inspecionar os valores UTF-16 que formam uma string:

string s = "😀";
foreach (char c in s)
{
Console.WriteLine($"U+{(int)c:X4}");
}

Saída:

U+D83D
U+DE00

➡️ Esses são os dois chars que, juntos, formam o emoji 😀 (U+1F600).


✅ Resumo final

ConceitoMétodoMede o quêEmoji “😀” retorna
Code units (UTF-16)texto.LengthNúmero de chars2
Code points (Unicode)texto.EnumerateRunes().Count()Pontos de código1
Elementos visuais (graphemes)new StringInfo(texto).LengthInTextElementsO que o usuário vê1