C# Escapes e Strings Literais
Uma string começa e termina com aspas. E se o texto tiver aspas dentro, como Ela disse: "Oi!"? E se precisar de uma quebra de linha, de uma tabulação, ou de um caminho do Windows cheio de barras, como C:\Users\ana? Para isso o C# tem as sequências de escape (\", \n, \\…) e dois tipos especiais de string: a string literal @"…" e a string bruta """…""". Nesta aula você vai ver os três e saber qual escolher em cada caso.
- Por que
"Ela disse: "Oi!""não compila e como resolver com\". - As sequências de escape:
\n(nova linha),\t(tabulação),\\,\',\u00e9e o novo\eC# 13. - A armadilha do caminho
"C:\novo\tabela.txt". - Strings literais
@"…": barras sem escape e texto em várias linhas. - Strings brutas
"""…"""C# 11: textos com aspas, JSON e interpolação com$$""", e os erros reais.
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: um sinal de "atenção, o próximo é especial"
Imagine que você está ditando um recado por telefone e precisa dizer "abre aspas". Se você só falar a palavra "aspas", a pessoa pode escrever a palavra em vez do símbolo. Então vocês combinam um sinal: quando você disser "símbolo: aspas", ela escreve ".
Em C#, esse sinal é a barra invertida \. Dentro de uma string, ela avisa: "o próximo caractere não é o que parece". \" quer dizer "uma aspa de verdade, não o fim do texto"; \n quer dizer "uma quebra de linha". Dizemos que a barra "escapa" o caractere seguinte do seu significado normal, e daí o nome sequência de escape.
1. O problema das aspas
Console.WriteLine("Ela disse: "Oi!"");
$ dotnet run problema.cs /home/ana/cs/problema.cs(1,32): error CS1003: Erro de sintaxe, "," esperado /home/ana/cs/problema.cs(1,35): error CS1003: Erro de sintaxe, "," esperado Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O C# lê a string "Ela disse: " e acha que ela acabou na segunda aspa. Depois encontra Oi! solto, fora de qualquer string, e outra string vazia "". A mensagem ", esperado" é o compilador tentando adivinhar: "se são vários valores, cadê a vírgula entre eles?". O conserto é avisar que aquelas aspas do meio são parte do texto.
2. As sequências de escape
Console.WriteLine("Ela disse: \"Oi!\"");
Console.WriteLine("Linha 1\nLinha 2");
Console.WriteLine("Nome\tIdade");
Console.WriteLine("Ana\t29");
Console.WriteLine("C:\\Users\\ana\\notas.txt");
Console.WriteLine('\'');
Console.WriteLine("Caf\u00e9 \u2764");
$ dotnet run escapes.cs Ela disse: "Oi!" « \" virou uma aspa Linha 1 « \n quebrou a linha Linha 2 Nome Idade « \t pulou para a próxima coluna de tabulação Ana 29 C:\Users\ana\notas.txt « cada \\ virou uma barra só ' « \' é uma aspa simples num char Café ❤ « \u seguido do código Unicode
- \"
- Uma aspa dupla dentro da string, sem terminá-la.
- \n
- New line, "nova linha". O texto continua na linha de baixo. Um
WriteLine("a\nb")mostra duas linhas. - \t
- Tab, a tabulação. O terminal pula para a próxima "parada" (em geral, de 8 em 8 colunas). Bom para colunas simples; para alinhar de verdade, use
{valor,10}(aula Formatar Números). - \\
- Uma barra invertida de verdade. Como a barra é o sinal de escape, para escrever uma você precisa de duas.
- '\''
- Num
char(aspas simples), a aspa simples também precisa de escape. Numa string,"'"não precisa. - \u00e9
- Um caractere pelo seu código Unicode, em hexadecimal, com 4 dígitos:
00e9é oé,2764é o coração. Útil para caracteres que você não tem no teclado.
Cada sequência de escape ocupa dois caracteres no código, mas é um caractere só no texto: "a\tb\n".Length é 4 (a, tabulação, b, quebra de linha), e "\\".Length é 1.
| Escape | Nome | Resultado |
|---|---|---|
\" | aspas duplas | " |
\' | aspas simples | ' |
\\ | barra invertida | \ |
\n | nova linha (line feed) | quebra de linha |
\r | retorno de carro (carriage return) | volta ao começo da linha (o Windows usa \r\n nos arquivos) |
\t | tabulação | salto até a próxima coluna |
\0 | nulo | o caractere de código 0 |
\u00e9 | Unicode (4 dígitos hexadecimais) | é |
\e C# 13 | escape (código 27) | começa comandos de cor e estilo do terminal |
O \e e as cores do terminal C# 13
Os terminais entendem comandos que começam com o caractere de código 27, chamado ESC. Até o C# 12, escrevia-se \u001b; desde o C# 13 há o atalho \e:
Console.WriteLine("\e[1mnegrito\e[0m normal");
Console.WriteLine((int)'\e');
$ dotnet run esc.cs negrito normal « \e[1m liga o negrito; \e[0m volta ao normal 27
Num terminal de verdade, a palavra aparece em negrito e os comandos ficam invisíveis. Isso é um detalhe do terminal, não do C#: se a saída for para um arquivo, os códigos aparecem lá como caracteres estranhos.
Experimente: mude o recado, acrescente mais \n e \t, e tente mostrar o caminho D:\fotos\2026.
Console.WriteLine("Recado da Ana:\n\t\"Volto às 14h.\"\n\t— Ana");
Console.WriteLine("Arquivo: C:\\Users\\ana\\recado.txt");
3. A armadilha do caminho do Windows
Caminhos do Windows usam a barra invertida, e aí mora um perigo: o C# lê as barras como escapes.
Console.WriteLine("C:\novo\tabela.txt");
$ dotnet run caminho.cs C: ovo abela.txt
O \n de \novo virou uma quebra de linha, e o \t de \tabela virou uma tabulação. O pior: não há erro nem aviso, porque \n e \t são escapes válidos. Se a barra vier antes de uma letra que não forma escape, aí sim o compilador reclama (CS1009, em Quando dá errado).
Há dois consertos: dobrar todas as barras ("C:\\novo\\tabela.txt") ou, bem mais legível, usar uma string literal.
Caminhos do Linux, como /home/ana/cs/notas.txt, usam a barra normal /, que não é escape. Para montar caminhos que funcionem nos dois sistemas, use Path.Combine (aula Pastas e Caminhos).
4. String literal: @"…"
Com um @ antes das aspas, a string vira uma string literal (em inglês, verbatim string, "palavra por palavra"): a barra invertida perde o poder de escape, e o texto é lido exatamente como está.
string caminho = @"C:\pasta\novo\tabela.txt"; Console.WriteLine(caminho); Console.WriteLine(@"Ela disse: ""Oi!"""); string poema = @"Batatinha quando nasce espalha a rama pelo chão"; Console.WriteLine(poema); Console.WriteLine(@"\n não é quebra aqui");
$ dotnet run verbatim.cs C:\pasta\novo\tabela.txt « as barras ficaram como estão Ela disse: "Oi!" « numa string @, aspas se escrevem dobradas: "" Batatinha quando nasce « a quebra de linha do código entrou no texto espalha a rama pelo chão \n não é quebra aqui
- @"C:\pasta\novo"
- Nenhum escape funciona:
\né uma barra e umn. Perfeito para caminhos do Windows e para expressões regulares (aula Regex). - ""
- Como a barra não escapa mais nada, a única forma de pôr uma aspa dentro de uma string
@é dobrá-la:""vira". - várias linhas
- A string
@pode atravessar linhas do código, e as quebras entram no texto. Cuidado: os espaços do começo das linhas também entram.
O @ combina com a interpolação: $@"C:\Users\{nome}\Documentos" (ou @$"…", tanto faz a ordem) põe o valor de nome no caminho e mantém as barras.
Missão: o caminho do arquivo da Ana saiu quebrado em duas linhas, com uma tabulação no meio. Conserte a string (com @ ou com barras dobradas) para aparecer C:\novo\tabela.txt.
C:\novo\tabela.txt
string arquivo = "C:\novo\tabela.txt"; Console.WriteLine(arquivo);
string arquivo = @"C:\novo\tabela.txt"; Console.WriteLine(arquivo);
5. String bruta: """…""" C# 11
A string @ resolve as barras, mas as aspas ainda precisam ser dobradas, e os espaços de recuo entram no texto. A string bruta (raw string literal) resolve tudo: ela começa com três aspas (ou mais) e, lá dentro, nada é especial: nem barras, nem aspas.
string json = """
{
"nome": "Ana",
"cidade": "Recife"
}
""";
Console.WriteLine(json);
Console.WriteLine("""Ela disse: "Oi!" e saiu.""");
$ dotnet run raw.cs
{ « o recuo de 4 espaços sumiu
"nome": "Ana", « os 2 espaços extras ficaram
"cidade": "Recife"
}
Ela disse: "Oi!" e saiu. « aspas sem escape nenhum
- """ e uma quebra de linha
- Numa string bruta de várias linhas, as três aspas de abertura ficam sozinhas no fim da linha, e o texto começa na linha de baixo.
- o recuo
- As três aspas de fechamento marcam a margem. Os espaços que estão antes delas (aqui, 4) são retirados de todas as linhas. Por isso o JSON saiu sem recuo, mas com os 2 espaços a mais das linhas de dentro. Assim, o texto pode ficar recuado junto com o código, sem que esse recuo vá para a tela.
- a primeira e a última quebra
- A quebra logo depois das aspas de abertura e a quebra antes das de fechamento não entram no texto.
- """Ela disse: "Oi!" e saiu."""
- Também existe a forma de uma linha só: as três aspas, o texto e as três aspas.
Se o texto tiver três aspas seguidas, abra e feche com quatro (""""), e assim por diante: a string só termina com a mesma quantidade de aspas com que começou.
String bruta com interpolação: $""" e $$"""
Com $ na frente, a string bruta ganha lacunas, como na aula Interpolação. Num JSON, porém, as chaves fazem parte do texto. A solução é usar dois cifrões: aí as lacunas passam a ser {{ }}, e uma chave sozinha é só uma chave.
string nome = "Ana";
int idade = 29;
string json = $$"""
{
"nome": "{{nome}}",
"idade": {{idade}}
}
""";
Console.WriteLine(json);
string ola = $"""Olá, "{nome}"!""";
Console.WriteLine(ola);
$ dotnet run rawinterp.cs
{
"nome": "Ana",
"idade": 29
}
Olá, "Ana"!
- $$"""
- A quantidade de
$diz quantas chaves formam uma lacuna. Com$$,{{nome}}é lacuna, e{sozinha aparece no texto. - $"""Olá, "{nome}"!"""
- Com um
$só, a lacuna é{nome}, como na interpolação comum, e as aspas continuam livres.
Qual usar?
| Situação | Use | Exemplo |
|---|---|---|
| Texto comum, talvez com uma quebra de linha | string normal com escapes | "Total:\n10 itens" |
| Uma ou duas aspas dentro | string normal com \" | "Ela disse: \"Oi!\"" |
| Caminho do Windows, expressão regular | string literal | @"C:\pasta\arquivo.txt" |
| Texto de várias linhas, com aspas, JSON, HTML, SQL | string bruta | """…""" |
| JSON com valores de variáveis | string bruta interpolada | $$"""{ "nome": "{{nome}}" }""" |
Código antigo usa muito @"…" para textos de várias linhas, porque a string bruta só chegou no C# 11 (.NET 7, 2022). No código novo, prefira a bruta para textos grandes.
Quando dá errado
error CS1009: Sequência de escape não reconhecida
Console.WriteLine("C:\pasta\arquivo.txt");
$ dotnet run ee1.cs /home/ana/cs/ee1.cs(1,22): error CS1009: Sequência de escape não reconhecida Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O que significa: \p não é um escape que o C# conhece. A coluna 22 aponta a barra de \pasta. Repare que o \a de \arquivo passaria sem erro: \a é um escape antigo (o "bipe" dos terminais).
Como consertar: @"C:\pasta\arquivo.txt" ou "C:\\pasta\\arquivo.txt".
error CS1010: Newline em constante
Console.WriteLine("Olá, mundo!);
$ dotnet run ee4.cs /home/ana/cs/ee4.cs(1,19): error CS1010: Newline em constante /home/ana/cs/ee4.cs(1,33): error CS1026: ) esperado /home/ana/cs/ee4.cs(1,33): error CS1002: ; esperado Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O que significa: "quebra de linha dentro de uma constante": a string começou na coluna 19 e a linha acabou sem a aspa de fechamento. O C# engoliu o ); como parte do texto, e por isso também reclama da falta deles. Uma string normal não pode atravessar linhas.
Como consertar: feche a aspa: "Olá, mundo!");. Para texto de várias linhas, use \n, @"…" ou """…""".
error CS8997: Literal de cadeia de caracteres não terminada. numa string bruta
string texto = """Linha um
Linha dois
""";
$ dotnet run ee2.cs /home/ana/cs/ee2.cs(1,27): error CS8997: Literal de cadeia de caracteres não terminada. /home/ana/cs/ee2.cs(1,27): error CS1003: Erro de sintaxe, "," esperado /home/ana/cs/ee2.cs(3,9): error CS8997: Literal de cadeia de caracteres não terminada. /home/ana/cs/ee2.cs(3,9): error CS1002: ; esperado Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O que significa: o texto começou na mesma linha das três aspas. Para o C#, isso é uma string bruta de uma linha só, que precisaria fechar com """ antes do fim da linha. Como não fechou, ela "não terminou".
Como consertar: numa string bruta de várias linhas, as aspas de abertura ficam sozinhas e o texto começa na linha de baixo:
string texto = """
Linha um
Linha dois
""";
error CS8999: A linha não começa com o mesmo espaço em branco que a linha de fechamento da literal de cadeia de caracteres bruta.
string texto = """
Linha um
Linha dois
""";
$ dotnet run ee3.cs /home/ana/cs/ee3.cs(3,1): error CS8999: A linha não começa com o mesmo espaço em branco que a linha de fechamento da literal de cadeia de caracteres bruta. Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O que significa: as aspas de fechamento estão recuadas 4 espaços, e isso é a margem. A linha 3 tem só 2 espaços, ou seja, está à esquerda da margem, e o C# não sabe o que fazer com ela.
Como consertar: recue todas as linhas pelo menos até onde estão as aspas de fechamento (ou puxe as aspas de fechamento para a esquerda).
O que significa: uma barra invertida formou um escape sem você querer, como o \n de C:\novo. Não há erro nem aviso.
Como consertar: use @"…" para textos com barras invertidas.
Referência
| Forma | Escapes com \ | Aspas dentro | Várias linhas | Interpolação |
|---|---|---|---|---|
"…" | sim | \" | não (use \n) | $"…{x}…" |
@"…" | não | "" | sim (o recuo entra) | $@"…{x}…" |
"""…""" C# 11 | não | livres | sim (o recuo sai) | $"""…{x}…""", $$"""…{{x}}…""" |
Exercícios
1. Aspas dentro
Complete para mostrar O livro "Dom Casmurro":
2. Duas linhas
Qual escape quebra a linha?
3. O símbolo da string literal
Complete para as barras ficarem como estão:
4. Quanto vale "a\nb".Length?
5. O que Console.WriteLine("C:\novo"); mostra?
6. Numa string @"…", como se escreve uma aspa dupla?
Missão final: o cardápio do café
Missão: a Ana escreveu o cardápio do café dela numa string só, com aspas e três linhas, e o programa nem compila. Reescreva com uma string bruta (""") para aparecer exatamente o texto abaixo, sem espaços no começo das linhas.
Bem-vindo ao "Café da Ana" Pão de queijo Café com leite
string cardapio = "Bem-vindo ao "Café da Ana" Pão de queijo Café com leite"; Console.WriteLine(cardapio);
string cardapio = """
Bem-vindo ao "Café da Ana"
Pão de queijo
Café com leite
""";
Console.WriteLine(cardapio);
Depois, tente fazer o mesmo com uma string normal (com \" e \n) e com uma string literal (@"…", com ""). Qual ficou mais fácil de ler?
Resumo
- A barra invertida
\começa uma sequência de escape:\",\\,\n,\t,\u00e9,\eC# 13. Cada uma é um caractere só. "C:\novo"vira quebra de linha sem aviso. Escape desconhecido (\p) dáCS1009.@"…": string literal. Barras ficam como estão, aspas se dobram (""), pode ter várias linhas."""…""": string bruta C# 11. Nada é especial lá dentro; as aspas de fechamento marcam a margem, e o recuo sai do texto.$"""…{x}…"""interpola;$$"""…{{x}}…"""deixa as chaves simples livres (JSON).- String normal sem fechar:
CS1010. Bruta com texto na linha das aspas:CS8997. Linha fora da margem:CS8999.