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.

Você vai aprender
  • Por que "Ela disse: "Oi!"" não compila e como resolver com \".
  • As sequências de escape: \n (nova linha), \t (tabulação), \\, \', \u00e9 e o novo \e C# 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.

EscapeNomeResultado
\"aspas duplas"
\'aspas simples'
\\barra invertida\
\nnova linha (line feed)quebra de linha
\rretorno de carro (carriage return)volta ao começo da linha (o Windows usa \r\n nos arquivos)
\ttabulaçãosalto até a próxima coluna
\0nuloo caractere de código 0
\u00e9Unicode (4 dígitos hexadecimais)é
\e C# 13escape (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.

E no Linux?

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 um n. 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çãoUseExemplo
Texto comum, talvez com uma quebra de linhastring normal com escapes"Total:\n10 itens"
Uma ou duas aspas dentrostring normal com \""Ela disse: \"Oi!\""
Caminho do Windows, expressão regularstring literal@"C:\pasta\arquivo.txt"
Texto de várias linhas, com aspas, JSON, HTML, SQLstring bruta"""…"""
JSON com valores de variáveisstring 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).

Uma quebra de linha ou uma tabulação apareceu no meio do texto

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

FormaEscapes com \Aspas dentroVárias linhasInterpolação
"…"sim\"não (use \n)$"…{x}…"
@"…"não""sim (o recuo entra)$@"…{x}…"
"""…""" C# 11nãolivressim (o recuo sai)$"""…{x}…""", $$"""…{{x}}…"""

Exercícios

1. Aspas dentro

Complete para mostrar O livro "Dom Casmurro":

"O livro "

2. Duas linhas

Qual escape quebra a linha?

"OiTchau"

3. O símbolo da string literal

Complete para as barras ficarem como estão:

string pasta = "C:\Users\ana";

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, \e C# 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.