C# Métodos de String
Na aula Strings você aprendeu a criar, medir e comparar textos. Agora vem a caixa de ferramentas: tirar espaços que o usuário digitou sem querer, procurar uma palavra, recortar o dia de uma data, trocar uma palavra por outra, separar uma lista em itens. Cada uma dessas tarefas é um método da string, uma ação que você pede escrevendo texto.Metodo(...). Nesta aula você vai conhecer os mais usados, o que cada um devolve e como eles quebram quando recebem uma posição que não existe.
- Limpar:
Trim,TrimStart,TrimEnde as maiúsculas comToUpper/ToLower. - Procurar:
Contains,StartsWith,EndsWith,IndexOfe o famoso-1. - Recortar:
Substringe os intervalosdata[..2]. - Trocar e dividir:
Replace,Split,string.Join,PadLeft/PadRight,Insert/Remove. - Encadear métodos (
texto.Trim().ToLower()) e os erros reais quando a posição não existe.
Todos os programas desta aula foram rodados com o .NET 10 na máquina fictícia da Ana (usuária ana, computador notebook), na pasta ~/cs, com dotnet run arquivo.cs.
A ideia: pedir para a string fazer algo
Pense na string como um funcionário que sabe fazer várias tarefas com o próprio texto. Você chama pelo nome e pede: "nome, me dá você em maiúsculas" (nome.ToUpper()), "frase, você contém a palavra roupa?" (frase.Contains("roupa")).
Duas regras valem para todos os métodos desta aula:
- O ponto liga o texto ao método, e os parênteses vêm sempre, mesmo vazios:
nome.Trim(). O que vai dentro dos parênteses são os argumentos, os detalhes do pedido:frase.Replace("café", "chá"). - A string original nunca muda. Strings são imutáveis (aula Strings): o método devolve um resultado novo. Se você quer usar esse resultado depois, guarde numa variável:
email = email.Trim();.
1. Maiúsculas e minúsculas
string nome = "Ana Souza"; Console.WriteLine(nome.ToUpper()); Console.WriteLine(nome.ToLower()); Console.WriteLine(nome);
$ dotnet run caixa.cs ANA SOUZA ana souza Ana Souza « a original não mudou
ToUpper ("para cima") e ToLower ("para baixo") seguem as regras do idioma do computador e conhecem os acentos ("ação" vira "AÇÃO"). Os detalhes, inclusive o "i" turco e o ToUpperInvariant, estão em Strings.
2. Limpar espaços: Trim
Quando alguém digita um e-mail, é comum sobrar um espaço no começo ou no fim. Para o computador, " ana@email.com" e "ana@email.com" são textos diferentes. O Trim ("aparar") tira os espaços das pontas:
string digitado = " ana@email.com ";
Console.WriteLine("[" + digitado + "]");
Console.WriteLine("[" + digitado.Trim() + "]");
Console.WriteLine("[" + digitado.TrimStart() + "]");
Console.WriteLine("[" + digitado.TrimEnd() + "]");
Console.WriteLine("[" + "...oi!!!".Trim('.', '!') + "]");
$ dotnet run trim.cs [ ana@email.com ] [ana@email.com] « Trim: as duas pontas [ana@email.com ] « TrimStart: só o começo [ ana@email.com] « TrimEnd: só o fim [oi] « Trim com caracteres escolhidos
- "[" + … + "]"
- Os colchetes são só um truque para ver os espaços na tela. Sem eles, espaços no fim da linha são invisíveis.
- Trim()
- Tira espaços, tabulações e quebras de linha do começo e do fim. Os espaços do meio ficam:
" Ana Souza ".Trim()dá"Ana Souza". - Trim('.', '!')
- Com argumentos, tira das pontas os caracteres que você escolheu (em aspas simples, porque são
char).
3. Procurar: Contains, StartsWith, EndsWith, IndexOf
string frase = "O rato roeu a roupa do rei de Roma";
Console.WriteLine(frase.Contains("roupa"));
Console.WriteLine(frase.Contains("Roupa"));
Console.WriteLine(frase.Contains("ROMA", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(frase.StartsWith("O rato"));
Console.WriteLine(frase.EndsWith("Roma"));
Console.WriteLine(frase.IndexOf("ro"));
Console.WriteLine(frase.LastIndexOf("ro"));
Console.WriteLine(frase.IndexOf('R'));
Console.WriteLine(frase.IndexOf("gato"));
$ dotnet run procurar.cs True « "roupa" aparece na frase False « maiúsculas contam: "Roupa" não aparece True « ignorando maiúsculas, "ROMA" aparece True « começa com "O rato" True « termina com "Roma" 7 « o primeiro "ro" (de "roeu") começa na posição 7 14 « o último "ro" (de "roupa") começa na posição 14 30 « o 'R' de "Roma" -1 « "gato" não está na frase
- Contains("roupa")
- "Contém?" Responde
trueoufalse. Diferencia maiúsculas, a não ser que você passeStringComparison.OrdinalIgnoreCasecomo segundo argumento. - StartsWith / EndsWith
- "Começa com?" e "termina com?". Muito usados com nomes de arquivo:
arquivo.EndsWith(".txt"). - IndexOf("ro")
- "Em que posição está?" Devolve a posição do primeiro caractere da primeira ocorrência, contando do zero.
LastIndexOfprocura a última. Aceita uma string ("ro") ou umchar('R'). - -1
- Quando o texto não é encontrado,
IndexOfdevolve-1, uma posição que não existe. Sempre confira o-1antes de usar a posição; senão, o próximo método quebra (veja Quando dá errado).
4. Recortar: Substring e intervalos
Para pegar um pedaço do texto, diga onde ele começa e quantos caracteres tem:
string data = "17/10/2026"; string dia = data.Substring(0, 2); string mes = data.Substring(3, 2); string ano = data.Substring(6); Console.WriteLine(dia + " | " + mes + " | " + ano); Console.WriteLine(data[..2]); Console.WriteLine(data[3..5]); Console.WriteLine(data[6..]); Console.WriteLine(data[^4..]);
$ dotnet run recortar.cs 17 | 10 | 2026 17 10 2026 2026
| Posição | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| Caractere | 1 | 7 | / | 1 | 0 | / | 2 | 0 | 2 | 6 |
"17/10/2026": o mês começa na posição 3 e tem 2 caracteres.- Substring(0, 2)
- "Pedaço a partir da posição 0, com 2 caracteres". O segundo número é o tamanho, não a posição final:
Substring(3, 2)pega as posições 3 e 4. - Substring(6)
- Com um número só: da posição 6 até o fim.
- data[..2] C# 8
- O intervalo (range) diz "do começo até a posição 2, sem incluir a 2".
data[3..5]pega 3 e 4;data[6..], da 6 até o fim;data[^4..], os 4 últimos. Aqui os dois números são posições (início e fim), não posição e tamanho. Os detalhes estão em Índices e Intervalos.
Qual usar? Os dois funcionam. O intervalo é mais curto e ótimo para "os 3 primeiros" ([..3]) e "os 4 últimos" ([^4..]). O Substring aparece em todo código antigo e é o que você vai ver em muitos tutoriais.
5. Trocar, inserir e remover
string frase = "Eu gosto de café. Café é bom.";
Console.WriteLine(frase.Replace("café", "chá"));
Console.WriteLine(frase.Replace("Café", "Chá").Replace("café", "chá"));
Console.WriteLine("1.234,50".Replace(".", "").Replace(",", "."));
Console.WriteLine("a-b-c".Replace("-", ""));
Console.WriteLine("Ana Souza".Remove(3));
Console.WriteLine("Ana Souza".Insert(3, " M."));
$ dotnet run trocar.cs Eu gosto de chá. Café é bom. « só o "café" minúsculo foi trocado Eu gosto de chá. Chá é bom. « dois Replace seguidos 1234.50 « tirou o ponto e trocou a vírgula por ponto abc « trocar por "" é apagar Ana « Remove(3): apaga da posição 3 até o fim Ana M. Souza « Insert(3, …): enfia o texto na posição 3
- Replace("café", "chá")
- "Troque todas as ocorrências do primeiro pelo segundo". Diferencia maiúsculas.
- .Replace(…).Replace(…)
- Como o
Replacedevolve uma string, dá para chamar outro método direto nela. Isso se chama encadear; veja a seção 8. - Remove(3) e Insert(3, " M.")
- Apagar a partir de uma posição e enfiar um texto numa posição. Menos usados, mas úteis.
6. Dividir e juntar: Split e string.Join
A lista de compras da Ana chegou num texto só, separado por ponto e vírgula. O Split ("dividir") corta o texto em pedaços e devolve um array de strings (uma fileira de textos numerados, aula Arrays). O string.Join ("juntar") faz o contrário:
string compras = "arroz;feijão;café;leite";
string[] itens = compras.Split(';');
Console.WriteLine(itens.Length);
Console.WriteLine(itens[0]);
Console.WriteLine(itens[3]);
Console.WriteLine(string.Join(", ", itens));
Console.WriteLine(string.Join(" | ", itens));
string frase = " muitos espaços aqui ";
string[] palavras = frase.Split(' ', StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(palavras.Length);
Console.WriteLine(string.Join("-", palavras));
$ dotnet run split.cs 4 « quatro itens arroz « o primeiro, posição 0 leite « o último, posição 3 arroz, feijão, café, leite arroz | feijão | café | leite 3 « sem as "palavras vazias" entre espaços seguidos muitos-espaços-aqui
- string[] itens = compras.Split(';');
string[]é "array de strings". O';'é o separador (umchar, entre aspas simples), e ele some do resultado.itens.Lengthdiz quantos pedaços saíram;itens[0]é o primeiro.- string.Join(", ", itens)
- Junta todos os itens, com
", "entre eles (não no fim). Repare que éstring.Join, chamado no tipo, e nãoitens.Join. - StringSplitOptions.RemoveEmptyEntries
- "Remova as entradas vazias". Sem isso, cada par de espaços seguidos geraria um pedaço vazio (
"") no array.
Experimente: acrescente itens à lista, troque o separador do Join por " e " ou "\n" (quebra de linha), e mostre quantos itens há. O que acontece se a lista terminar com ;?
string compras = "arroz;feijão;café";
string[] itens = compras.Split(';');
Console.WriteLine("Itens: " + itens.Length);
Console.WriteLine(string.Join(", ", itens));
Console.WriteLine("Primeiro: " + itens[0].ToUpper());
7. Preencher: PadLeft e PadRight
Para alinhar colunas, os métodos Pad ("enchimento") completam o texto até um tamanho:
Console.WriteLine("Arroz".PadRight(10, '.') + "R$ 5,90");
Console.WriteLine("Feijão".PadRight(10, '.') + "R$ 8,50");
Console.WriteLine("7".PadLeft(3, '0'));
Console.WriteLine("[" + "oi".PadLeft(5) + "]");
Console.WriteLine(new string('=', 20));
$ dotnet run pad.cs Arroz.....R$ 5,90 Feijão....R$ 8,50 007 [ oi] ====================
- PadRight(10, '.')
- Completa à direita com pontos até o texto ter 10 caracteres.
"Arroz"tem 5, então ganha 5 pontos;"Feijão"tem 6, ganha 4. Os preços ficam alinhados. - PadLeft(3, '0')
- Completa à esquerda. Bom para números com zeros na frente:
007. - PadLeft(5)
- Sem o segundo argumento, completa com espaços.
- new string('=', 20)
- Não é um método, mas é útil aqui: cria uma string com o caractere
'='repetido 20 vezes, ótimo para linhas de separação.
Para alinhar números e preços, a formatação com {preco,10:C} é ainda mais prática (aula Formatar Números).
8. Encadear métodos
Como cada método devolve uma string nova, você pode chamar o próximo método direto no resultado, da esquerda para a direita:
string resposta = " SIM ";
string limpa = resposta.Trim().ToLower();
Console.WriteLine("[" + limpa + "]");
Console.WriteLine(limpa == "sim");
Console.WriteLine(" Ana Souza ".Trim().ToUpper().Replace(" ", "_"));
$ dotnet run cadeia.cs [sim] True ANA_SOUZA
resposta.Trim()devolve"SIM"."SIM".ToLower()devolve"sim", que vai paralimpa.- Na última linha:
"Ana Souza"→"ANA SOUZA"→"ANA_SOUZA".
Encadear é ótimo para duas ou três etapas. Com mais, quebre em variáveis com nomes claros: fica mais fácil achar onde está um erro.
Missão: a pessoa respondeu " SIM ", com espaços e em maiúsculas, e o programa precisa da resposta limpa: [sim]. Encadeie Trim() e ToLower() na linha marcada.
[sim] Confirmou? True
string resposta = " SIM ";
string limpa = resposta; // limpe aqui
Console.WriteLine("[" + limpa + "]");
Console.WriteLine("Confirmou? " + (limpa == "sim"));
string resposta = " SIM ";
string limpa = resposta.Trim().ToLower();
Console.WriteLine("[" + limpa + "]");
Console.WriteLine("Confirmou? " + (limpa == "sim"));
Formas diferentes de fazer a mesma coisa
| Tarefa | Formas | Qual usar |
|---|---|---|
| Os 3 primeiros caracteres | s.Substring(0, 3) · s[..3] | s[..3] no código novo; as duas quebram se o texto tiver menos de 3. |
| Contém, sem ligar para maiúsculas | s.ToLower().Contains("ana") · s.Contains("ana", StringComparison.OrdinalIgnoreCase) | A segunda: não cria uma string nova e não depende do idioma. |
Trocar ; por , | s.Replace(";", ", ") · string.Join(", ", s.Split(';')) | Replace: mais simples. Use Split quando precisar mexer em cada item. |
| Saber se existe | s.IndexOf("x") != -1 · s.Contains("x") | Contains. Use IndexOf quando precisar da posição. |
Quando dá errado
System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
string nome = "Ana"; Console.WriteLine(nome.Substring(1, 5));
$ dotnet run em1.cs Unhandled exception. System.ArgumentOutOfRangeException: Index and length must refer to a location within the string. (Parameter 'length') at System.String.ThrowSubstringArgumentOutOfRange(Int32 startIndex, Int32 length) at System.String.Substring(Int32 startIndex, Int32 length) at Program.<Main>$(String[] args) in /home/ana/cs/em1.cs:line 2
O que significa: "a posição e o tamanho precisam caber dentro da string". A partir da posição 1 de "Ana" só há 2 caracteres, e você pediu 5. O (Parameter 'length') aponta o culpado: o argumento do tamanho. As linhas at System.String… são de dentro do .NET; a sua é a última, line 2.
Como consertar: confira o tamanho antes (nome.Length) ou use Substring(1), "até o fim".
System.ArgumentOutOfRangeException: length ('-1') must be a non-negative value. depois de um IndexOf
string email = "ana.email.com";
int arroba = email.IndexOf('@');
Console.WriteLine(arroba);
Console.WriteLine(email.Substring(arroba + 1));
Console.WriteLine(email.Substring(0, arroba));
$ dotnet run em2.cs
-1 « não tem @ no texto
ana.email.com « Substring(-1 + 1) = Substring(0): o texto todo, sem erro, mas errado
Unhandled exception. System.ArgumentOutOfRangeException: length ('-1') must be a non-negative value. (Parameter 'length')
Actual value was -1.
at System.ArgumentOutOfRangeException.ThrowNegative[T](T value, String paramName)
at System.ArgumentOutOfRangeException.ThrowIfNegative[T](T value, String paramName)
at System.String.ThrowSubstringArgumentOutOfRange(Int32 startIndex, Int32 length)
at System.String.Substring(Int32 startIndex, Int32 length)
at Program.<Main>$(String[] args) in /home/ana/cs/em2.cs:line 5
O que significa: o e-mail não tinha @, o IndexOf devolveu -1, e esse -1 foi usado como tamanho: "o tamanho (-1) precisa ser não negativo". Pior: a linha 4 não quebrou, só deu um resultado errado.
Como consertar: confira o -1 antes de usar a posição: if (arroba == -1) { … } (aula if e else), ou use email.Contains('@') antes.
error CS1503: Argumento 1: não é possível converter de "grupo de métodos" para "bool"
string nome = "Ana"; Console.WriteLine(nome.ToUpper);
$ dotnet run em3.cs /home/ana/cs/em3.cs(2,19): error CS1503: Argumento 1: não é possível converter de "grupo de métodos" para "bool" Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O que significa: faltaram os parênteses. Sem eles, nome.ToUpper é o nome do método (um "grupo de métodos"), e não o resultado de chamá-lo. A mensagem fala em bool porque o compilador tentou encaixar isso na primeira versão do WriteLine que encontrou.
Como consertar: nome.ToUpper(). Métodos sempre levam parênteses; propriedades, como Length, não.
error CS0029: Não é possível converter implicitamente tipo "string[]" em "string"
string compras = "arroz;feijão";
string itens = compras.Split(';');
$ dotnet run em4.cs /home/ana/cs/em4.cs(2,16): error CS0029: Não é possível converter implicitamente tipo "string[]" em "string" Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O que significa: o Split devolve vários textos (um string[]), e você tentou guardar numa variável de um texto.
Como consertar: string[] itens = compras.Split(';'); (ou var itens = …, aula var).
Trim (ou o Replace) "não funcionou"
O que significa: você escreveu email.Trim(); numa linha sozinha e depois usou email. O resultado foi jogado fora.
Como consertar: email = email.Trim();.
Referência
| Método | Devolve | Exemplo → resultado |
|---|---|---|
ToUpper(), ToLower() | string | "Ana".ToUpper() → "ANA" |
Trim(), TrimStart(), TrimEnd() | string | " oi ".Trim() → "oi" |
Contains(x) | bool | "banana".Contains("nan") → true |
StartsWith(x), EndsWith(x) | bool | "foto.png".EndsWith(".png") → true |
IndexOf(x), LastIndexOf(x) | int (ou -1) | "banana".IndexOf('n') → 2 |
Substring(inicio, tamanho) | string | "banana".Substring(1, 3) → "ana" |
s[inicio..fim] | string | "banana"[1..4] → "ana" |
Replace(velho, novo) | string | "banana".Replace("a", "o") → "bonono" |
Insert(pos, x), Remove(pos) | string | "oi".Insert(2, "!") → "oi!" |
Split(sep) | string[] | "a;b".Split(';') → ["a", "b"] |
string.Join(sep, itens) | string | string.Join("-", itens) → "a-b" |
PadLeft(n, c), PadRight(n, c) | string | "7".PadLeft(3, '0') → "007" |
new string(c, n) | string | new string('-', 3) → "---" |
Muitos aceitam um StringComparison no fim para ignorar maiúsculas: Contains, StartsWith, EndsWith, IndexOf, Replace. A lista completa, com StringBuilder, está em string e StringBuilder.
Exercícios
1. Tirar os espaços
Complete para tirar os espaços do começo e do fim:
2. Não achou
O que "banana".IndexOf("uva") devolve?
3. Recortar
Complete para pegar "10" de "17/10/2026" com Substring:
4. O que "a,b,,c".Split(',').Length devolve?
5. Depois de string s = " oi "; s.Trim();, quanto vale s.Length?
6. Em Substring(3, 2), o que é o 2?
Missão final: separar o e-mail
Missão: a Ana recebeu o e-mail " Ana.Souza@Email.COM ", com espaços e maiúsculas misturadas. Limpe (Trim e ToLower) e separe a parte antes do @ (o usuário) da parte depois (o domínio), usando IndexOf e Substring (ou Split). Não escreva os resultados à mão.
Usuário: ana.souza Domínio: email.com
string email = " Ana.Souza@Email.COM ";
// 1. limpe o e-mail
// 2. ache a posição do @
string usuario = "?";
string dominio = "?";
Console.WriteLine("Usuário: " + usuario);
Console.WriteLine("Domínio: " + dominio);
string email = " Ana.Souza@Email.COM ";
email = email.Trim().ToLower();
int arroba = email.IndexOf('@');
string usuario = email.Substring(0, arroba);
string dominio = email.Substring(arroba + 1);
Console.WriteLine("Usuário: " + usuario);
Console.WriteLine("Domínio: " + dominio);
Com Split, a solução fica: string[] partes = email.Trim().ToLower().Split('@'); e depois partes[0] e partes[1]. Teste também um e-mail sem @ e veja qual exceção aparece.
Resumo
- Métodos se chamam com ponto e parênteses:
texto.Trim(). Eles devolvem um resultado novo; a string original não muda. - Limpar:
Trim; maiúsculas:ToUpper/ToLower. - Procurar:
Contains,StartsWith,EndsWith(dãobool) eIndexOf(dá a posição, ou -1 se não achar). - Recortar:
Substring(inicio, tamanho)ous[inicio..fim](o fim não entra). Fora dos limites:ArgumentOutOfRangeException. - Trocar:
Replace. Dividir e juntar:Split(devolvestring[]) estring.Join. - Alinhar:
PadLeft/PadRight. Repetir:new string('-', 20). - Encadeie poucos métodos (
s.Trim().ToLower()) e sempre confira o-1doIndexOf.