C# Ler do Teclado (Console.ReadLine)
Até aqui, todo programa da Ana fazia sempre a mesma coisa: os valores estavam escritos no código. Para fazer uma calculadora, um jogo ou um cadastro, o programa precisa perguntar e esperar a resposta de quem está usando. Em C#, quem faz isso é o Console.ReadLine() ("ler linha do console"): ele para o programa, espera a pessoa digitar e apertar Enter, e entrega o que foi digitado como texto. Nesta aula você vai ver como usá-lo, por que o compilador avisa que a resposta "pode ser nula", e como transformar o texto em número sem o programa quebrar.
- Como ler uma linha com
Console.ReadLine()e mostrar uma pergunta antes comConsole.Write. - Por que o resultado é
string?e quando ele valenull. - Os avisos reais
CS8600,CS8602eCS8604, e o que acontece quando você os ignora. - Três jeitos de tratar o
null:is null,??eTrimpara respostas vazias. - Como ler números com
int.TryParseedecimal.TryParse, e por que oParsederruba o programa. - A pegadinha do ponto e da vírgula: por que
3.50virou315,00. - Como ler várias linhas num laço e mandar a entrada de um arquivo, com
<.
Todos os programas foram rodados com o .NET 10 (dotnet --version = 10.0.112, C# 14) na máquina fictícia da Ana (usuária ana, computador notebook), na pasta ~/cs, com dotnet run arquivo.cs. Nos terminais, o que vem depois de uma pergunta (como Ana em Qual é o seu nome? Ana) foi digitado pela Ana. Antes desta aula, é bom ter visto Texto → Número (Parse e TryParse).
A ideia: o atendente do balcão
Pense num atendente de padaria. Ele pergunta "o que vai ser?" e espera. Não adianta ele adivinhar: só continua quando você responde. E ele anota a resposta do jeito que ouviu, como palavras: se você disser "dois pães", ele anota as palavras "dois pães", e ainda precisa entender que "dois" é o número 2.
- O
Console.Write("O que vai ser? ")é a pergunta. - O
Console.ReadLine()é a espera: o programa fica parado até a pessoa apertar Enter. - O que ele devolve é sempre texto (
string), mesmo que a pessoa tenha digitado29. Transformar em número é outro passo. - E às vezes o cliente vai embora sem responder. No programa, isso é o
null: "não veio resposta nenhuma".
1. A primeira leitura
Console.Write("Qual é o seu nome? ");
string? nome = Console.ReadLine();
Console.WriteLine($"Olá, {nome}!");
- Console.Write("Qual é o seu nome? ");
- A pergunta. Com
Write(e nãoWriteLine), o cursor fica na mesma linha, logo depois do espaço, e a resposta aparece ao lado da pergunta. É o jeito mais comum. O espaço no fim do texto separa a pergunta da resposta. - Console.ReadLine()
- Para o programa e espera. Quando a pessoa aperta Enter, ele devolve tudo o que ela digitou naquela linha, sem o Enter.
- string? nome
- A variável que guarda a resposta. O tipo é
string?, "texto ounull". O?é o assunto da seção 2. - $"Olá, {nome}!"
- Usa a resposta, como qualquer outra variável.
$ dotnet run le.cs Qual é o seu nome? Ana « a Ana digita Ana e aperta Enter Olá, Ana!
Enquanto a Ana não aperta Enter, o programa fica esperando, para sempre se for preciso. Ela pode apagar e corrigir à vontade: o ReadLine só recebe a linha quando o Enter é apertado.
Nas caixas "Experimente", o programa pode pedir a entrada: aparece um campo no terminal da caixa, logo depois da pergunta, e você digita e tecla Enter. Ctrl+D é o fim da entrada (o ReadLine devolve null), e Ctrl+C ou o botão Parar interrompe. Por dentro há um truque: o navegador não deixa o programa ficar esperando o teclado, então, a cada Enter, o editor roda o programa de novo, desde o começo, com as linhas que você já digitou. A saída é a mesma; só muda o que depende do relógio, como DateTime.Now (veja O Editor do Guia). Nas missões desta aula, a entrada já vem pronta, escrita na caixa, para o resultado ser sempre o mesmo: é como se alguém tivesse digitado por você.
Missão: o programa lê o nome, mas não o usa. A entrada desta caixa é Bia. Troque a mensagem para Olá, Bia! Bem-vinda à lojinha., usando a variável nome (não escreva "Bia" no código: o programa tem de funcionar para qualquer nome).
Qual é o seu nome? Olá, Bia! Bem-vinda à lojinha.
Console.Write("Qual é o seu nome? ");
string? nome = Console.ReadLine();
Console.WriteLine("Olá! Bem-vinda à lojinha.");
Console.Write("Qual é o seu nome? ");
string? nome = Console.ReadLine();
Console.WriteLine($"Olá, {nome}! Bem-vinda à lojinha.");
2. Por que string?: quando a entrada acaba
O ReadLine pode devolver uma coisa que não é texto nenhum: null, que quer dizer "nada" (aula null e Tipos Anuláveis). Isso acontece quando a entrada acabou e não há mais linha para ler. Não é o mesmo que uma resposta vazia: se a pessoa só aperta Enter, chega "", um texto com zero letras. O null é "não veio linha".
Quando a entrada acaba?
- No terminal, quando a pessoa aperta Ctrl+D (no Linux e no macOS; no Windows é Ctrl+Z e Enter). É o sinal de "fim da entrada".
- Quando a entrada vem de um arquivo (seção 6) e as linhas do arquivo terminaram.
- Quando o programa roda sem ninguém para digitar, como num servidor.
Por isso o C# diz que o ReadLine devolve string? e não string. Como o guia usa as referências anuláveis (ligadas por padrão no .NET 10, aula Referências Anuláveis), o compilador confere se você está preparado para esse null. Veja o que acontece se a Ana escrever só string, sem o ?:
Console.Write("Qual é o seu nome? ");
string nome = Console.ReadLine();
Console.WriteLine($"Olá, {nome}! Seu nome tem {nome.Length} letras.");
$ dotnet run aviso.cs /home/ana/cs/aviso.cs(2,15): warning CS8600: Conversão de literal nula ou possível valor nulo em tipo não anulável. /home/ana/cs/aviso.cs(3,48): warning CS8602: Desreferência de uma referência possivelmente nula. Qual é o seu nome? Ana Olá, Ana! Seu nome tem 3 letras.
- warning
- São avisos, não erros: o programa compilou e rodou (aula Avisos do Compilador). Eles aparecem só quando o arquivo é compilado; se você rodar de novo sem mudar nada, o
dotnetreaproveita a compilação e não os mostra outra vez. Não é porque sumiram. (O editor do guia compila a cada Rodar, então mostra os avisos sempre.) - CS8600 (linha 2, coluna 15)
- "Conversão de um possível valor nulo em tipo não anulável": o
ReadLine()pode darnull, e você está guardando numastring, que promete nunca sernull. Em inglês: Converting null literal or possible null value to non-nullable type. - CS8602 (linha 3, coluna 48)
- "Desreferência de uma referência possivelmente nula": o
nome.Lengthpede o tamanho de algo que pode sernull. "Desreferenciar" é usar o ponto (.) para pegar alguma coisa de dentro de um objeto. Em inglês: Dereference of a possibly null reference.
Com a Ana digitando, tudo funcionou. Mas o aviso não é exagero. Veja o mesmo programa quando a entrada acaba: o < /dev/null manda para o programa uma entrada vazia, que acaba logo de cara, como se a Ana apertasse Ctrl+D antes de digitar qualquer coisa:
$ dotnet run aviso.cs < /dev/null Qual é o seu nome? Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object. at Program.<Main>$(String[] args) in /home/ana/cs/aviso.cs:line 3 $ echo $? 134
Unhandled exception = "exceção não tratada": o programa quebrou. NullReferenceException é a exceção de "usar um null como se fosse um objeto": Object reference not set to an instance of an object, "a referência não aponta para nenhum objeto". A linha culpada é a 3, o nome.Length, exatamente onde o CS8602 avisou. O código de saída 134 é o de um programa que terminou com exceção (aula Exceções).
string? e trate o null
Guarde a resposta do ReadLine() numa string? e decida o que fazer quando ela for null, com um dos jeitos da próxima seção. Nunca "cale" o aviso sem pensar: ele está apontando um jeito real de o programa quebrar.
3. Três jeitos de tratar o null
Jeito 1: perguntar com is null
Console.Write("Qual é o seu nome? ");
string? nome = Console.ReadLine();
if (nome is null)
{
Console.WriteLine();
Console.WriteLine("A entrada acabou: ninguém digitou nada.");
}
else
{
Console.WriteLine($"Olá, {nome}!");
}
$ dotnet run nulo.cs Qual é o seu nome? « a Ana aperta Ctrl+D (nada aparece na tela) A entrada acabou: ninguém digitou nada.
- nome is null
- "
nomeé nulo?". Dentro doelse, o compilador sabe quenomenão énull, e não avisa mais nada se você usarnome.Lengthali. (Também dá para escrevernome == null; ois nullé o jeito preferido no C# moderno.) - Console.WriteLine();
- Como a Ana não apertou Enter, o cursor ficou ao lado da pergunta. Esta linha vazia pula para a linha de baixo antes da mensagem.
Jeito 2: um valor no lugar, com ??
Muitas vezes, "a entrada acabou" e "a pessoa não digitou nada" podem ter o mesmo tratamento. O operador ?? ("se for nulo, use isto", aula Operadores ??, ?. e ??=) troca o null por um texto vazio já na leitura. Aí a variável pode ser uma string comum, sem ? e sem aviso:
Console.Write("Qual é o seu nome? ");
string nome = Console.ReadLine() ?? "";
nome = nome.Trim();
if (nome == "")
{
nome = "visitante";
}
Console.WriteLine($"Olá, {nome}! Seu nome tem {nome.Length} letras.");
- Console.ReadLine() ?? ""
- Se o
ReadLinedevolver um texto, fica o texto. Se devolvernull, fica"". O resultado nunca énull, por isso cabe numastring. - nome.Trim()
- "Aparar": tira os espaços do começo e do fim (aula Métodos de String). Quem digita muitas vezes deixa um espaço sobrando sem perceber.
- if (nome == "")
- Depois do
Trim, uma resposta só com espaços também vira"". Aqui o programa escolhe um nome padrão.
$ dotnet run vazio.cs Qual é o seu nome? Ana « a Ana digitou espaços antes e depois Olá, Ana! Seu nome tem 3 letras. $ dotnet run vazio.cs Qual é o seu nome? « a Ana só apertou Enter Olá, visitante! Seu nome tem 9 letras.
Jeito 3: string.IsNullOrWhiteSpace
Para perguntar tudo de uma vez ("é null, vazio ou só espaços?"), existe string.IsNullOrWhiteSpace(nome) ("é nulo ou espaço em branco"). Ele aparece no laço da seção 6.
Console.ReadLine()!?
Você vai ver em muitos exemplos na internet string nome = Console.ReadLine()!;. O ! no fim é o operador "eu garanto que não é nulo" (null-forgiving). Ele só cala o aviso: se a entrada acabar, o NullReferenceException acontece do mesmo jeito. Use ?? ou is null, que resolvem de verdade.
4. Ler números: TryParse, e não Parse
O ReadLine sempre devolve texto. Tentar guardar direto num int nem compila:
$ cat cs0029.cs
Console.Write("Quantos anos você tem? ");
int idade = Console.ReadLine();
Console.WriteLine(idade + 10);
$ dotnet run cs0029.cs
/home/ana/cs/cs0029.cs(2,13): error CS0029: Não é possível converter implicitamente tipo "string" em "int"
Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O texto "29" não é o número 29: é um '2' seguido de um '9'. Para virar número, ele precisa ser convertido. A primeira ideia costuma ser o int.Parse (aula Parse e TryParse):
Console.Write("Quantos anos você tem? ");
int idade = int.Parse(Console.ReadLine());
Console.WriteLine($"Daqui a 10 anos você terá {idade + 10}.");
$ dotnet run idade-parse.cs /home/ana/cs/idade-parse.cs(2,23): warning CS8604: Possível argumento de referência nula para o parâmetro 's' em 'int int.Parse(string s)'. Quantos anos você tem? 29 Daqui a 10 anos você terá 39. $ dotnet run idade-parse.cs Quantos anos você tem? vinte Unhandled exception. System.FormatException: The input string 'vinte' was not in a correct format. at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1 value) at System.Int32.Parse(String s) at Program.<Main>$(String[] args) in /home/ana/cs/idade-parse.cs:line 2 $ echo $? 134
Dois problemas de uma vez:
- O aviso
CS8604: "possível argumento nulo para o parâmetrosdeint.Parse(string s)". OParsequer umastringde verdade, e oReadLine()pode darnull. Em inglês: Possible null reference argument for parameter 's'. - A exceção
FormatException: The input string 'vinte' was not in a correct format, "o texto 'vinte' não está num formato correto". Basta a pessoa digitar uma letra para o programa inteiro cair.
O TryParse ("tentar converter") resolve os dois. Ele aceita null, não lança exceção e diz se deu certo:
Console.Write("Quantos anos você tem? ");
string? texto = Console.ReadLine();
if (int.TryParse(texto, out int idade))
{
Console.WriteLine($"Daqui a 10 anos você terá {idade + 10}.");
}
else
{
Console.WriteLine($"\"{texto}\" não é um número inteiro.");
}
- string? texto = Console.ReadLine();
- Primeiro, guarda o texto do jeito que veio, com
?. - int.TryParse(texto, out int idade)
- Tenta converter. Se conseguir, devolve
truee põe o número emidade. Se não conseguir (letras, vazio ounull), devolvefalseeidadefica 0. Oout int idadecria a variável ali mesmo (aula ref, out e in). - if (…) { … } else { … }
- O programa decide o que fazer nos dois casos, em vez de quebrar.
- \"{texto}\"
- O
\"põe aspas dentro do texto (aula Escapes), para mostrar exatamente o que a pessoa digitou.
$ dotnet run idade.cs « compilou sem nenhum aviso Quantos anos você tem? vinte "vinte" não é um número inteiro. $ dotnet run idade.cs Quantos anos você tem? 29 Daqui a 10 anos você terá 39.
Missão: a entrada desta caixa é vinte. Rode: o int.Parse derruba o programa com FormatException e código de saída 134. Troque-o por int.TryParse para que o programa mostre "vinte" não é um número inteiro. e termine normalmente (código 0).
Quantos anos você tem? "vinte" não é um número inteiro.
Console.Write("Quantos anos você tem? ");
string? texto = Console.ReadLine();
int idade = int.Parse(texto);
Console.WriteLine($"Daqui a 10 anos você terá {idade + 10}.");
Console.Write("Quantos anos você tem? ");
string? texto = Console.ReadLine();
if (int.TryParse(texto, out int idade))
{
Console.WriteLine($"Daqui a 10 anos você terá {idade + 10}.");
}
else
{
Console.WriteLine($"\"{texto}\" não é um número inteiro.");
}
Perguntar de novo até vir um número
Em vez de desistir na primeira resposta errada, o programa pode repetir a pergunta com um laço (aula do while):
int idade;
string? texto;
do
{
Console.Write("Quantos anos você tem? ");
texto = Console.ReadLine();
if (texto is null)
{
return;
}
} while (!int.TryParse(texto, out idade));
Console.WriteLine($"Daqui a 10 anos você terá {idade + 10}.");
- while (!int.TryParse(texto, out idade))
- Repete enquanto não conseguir converter. Quando conseguir, sai do laço com o número em
idade. - if (texto is null) { return; }
- Se a entrada acabar, não adianta perguntar de novo: nenhuma resposta vai chegar, e o laço ficaria infinito. O
return, no programa de nível superior, termina o programa.
$ dotnet run insiste.cs Quantos anos você tem? vinte Quantos anos você tem? « a Ana só apertou Enter Quantos anos você tem? 29 Daqui a 10 anos você terá 39.
5. Vírgula ou ponto? A pegadinha do pt-BR
Para preços e notas com casas decimais, use decimal.TryParse (ou double.TryParse). Ele converte do jeito do idioma do computador. No notebook da Ana, em português do Brasil, a vírgula separa os centavos e o ponto separa os milhares, como em R$ 1.234,50 (aula Cultura). Veja o que acontece com cada resposta:
Console.Write("Preço: ");
string? texto = Console.ReadLine();
if (decimal.TryParse(texto, out decimal preco))
{
Console.WriteLine($"Com 10% de desconto: {preco * 0.9m:C}");
}
else
{
Console.WriteLine("Preço inválido.");
}
$ dotnet run preco.cs Preço: 3,50 Com 10% de desconto: R$ 3,15 $ dotnet run preco.cs Preço: 3.50 Com 10% de desconto: R$ 315,00 « !!! o ponto foi lido como separador de milhar $ dotnet run preco.cs Preço: 1.234,50 Com 10% de desconto: R$ 1.111,05 $ dotnet run preco.cs Preço: abc Preço inválido.
| A Ana digitou | O decimal.TryParse entendeu (pt-BR) | Por quê |
|---|---|---|
3,50 | 3,50 | A vírgula é a casa decimal. |
3.50 | 350 | O ponto é separador de milhar, e o TryParse o ignora. Deu true, sem erro nenhum. |
1.234,50 | 1234,50 | Milhar com ponto e centavos com vírgula: o jeito brasileiro completo. |
abc | (falhou) | Não é número: devolve false. |
O 3.50 é o caso perigoso: o programa não quebra nem reclama, só calcula errado. Num computador em inglês, seria o contrário: 3.50 daria 3,50 e 3,50 daria 350. Por isso:
- diga na pergunta o formato que você espera:
Console.Write("Preço (ex.: 12,90): ");; - quando o número vem de um arquivo ou de outro programa, e não de uma pessoa, leia com uma cultura fixa (
CultureInfo.InvariantCulture), assunto da aula Cultura.
6. Várias linhas: ler num laço
A Ana quer somar os preços de uma compra, sem saber quantos itens são. O programa lê uma linha por volta e para quando ela aperta Enter numa linha vazia, ou quando a entrada acaba:
decimal total = 0m;
int itens = 0;
Console.WriteLine("Digite os preços (Enter numa linha vazia termina):");
while (true)
{
string? linha = Console.ReadLine();
if (string.IsNullOrWhiteSpace(linha))
{
break;
}
if (decimal.TryParse(linha, out decimal preco))
{
total += preco;
itens++;
}
else
{
Console.WriteLine($"Ignorado: \"{linha}\" não é um preço.");
}
}
Console.WriteLine($"{itens} itens, total {total:C}");
- while (true)
- Um laço "para sempre", que só termina pelo
break(aula break e continue). - string? linha = Console.ReadLine();
- Uma leitura por volta. Cada volta espera uma linha nova.
- string.IsNullOrWhiteSpace(linha)
- Verdade se a linha for
null(a entrada acabou), vazia ou só espaços. Nos três casos, o laço termina. - decimal.TryParse(…)
- Se for um preço, soma. Se não for, avisa e continua: um erro de digitação não perde a compra inteira.
- {total:C}
- O formato de moeda:
R$ 24,40no pt-BR (aula Formatar Números).
$ dotnet run soma.cs
Digite os preços (Enter numa linha vazia termina):
12,90
4,50
dez
Ignorado: "dez" não é um preço.
7
« linha vazia: a Ana só apertou Enter
3 itens, total R$ 24,40
A entrada vinda de um arquivo
O ReadLine lê da entrada padrão, que normalmente é o teclado. No terminal, o < troca o teclado por um arquivo (é o mesmo < do Guia Bash). Cada linha do arquivo vira uma resposta, e quando o arquivo acaba, o ReadLine devolve null:
$ cat precos.txt 12,90 4,50 dez 7 $ dotnet run soma.cs < precos.txt Digite os preços (Enter numa linha vazia termina): Ignorado: "dez" não é um preço. 3 itens, total R$ 24,40
Repare que os preços não aparecem na tela: eles não foram digitados, então o terminal não os mostrou. Só aparece o que o programa escreveu. O arquivo não tem linha vazia no fim: quem parou o laço foi o null do fim da entrada. É por isso que tratar o null importa: sem ele, este laço quebraria (ou nunca terminaria) com um arquivo.
7. Outras formas de ler, e qual usar
| Forma | O que faz | Quando usar |
|---|---|---|
Console.ReadLine() | Espera o Enter e devolve a linha inteira (string?). | Quase sempre: nomes, números, opções de menu. |
Console.ReadKey() | Devolve uma tecla assim que ela é apertada, sem esperar o Enter. | Jogos e menus de uma tecla, como "aperte qualquer tecla para continuar". Só funciona com um teclado de verdade: com a entrada vindo de um arquivo, ele lança InvalidOperationException. |
Console.Read() | Lê um caractere e devolve o código dele como int (−1 no fim da entrada). | Raramente. Ele também espera o Enter, e o próprio Enter vira um caractere lido depois. |
Console.In.ReadToEnd() | Lê tudo, até o fim da entrada, de uma vez. | Programas que recebem um arquivo pelo < e processam tudo junto. |
E para converter o que foi lido:
| Forma | Com texto inválido | Com null | Use? |
|---|---|---|---|
int.TryParse(texto, out int n) | devolve false | devolve false | Sim: é o certo para entrada de pessoas. |
int.Parse(texto) | FormatException | ArgumentNullException e o aviso CS8604 | Só quando o texto com certeza é um número (que o próprio programa gerou). |
Convert.ToInt32(texto) | FormatException | devolve 0, calado | Evite com entrada do usuário: um null vira 0 sem você perceber. |
Quando dá errado
warning CS8600: Conversão de literal nula ou possível valor nulo em tipo não anulável.
O que significa: você guardou Console.ReadLine() numa string sem ?. Se a entrada acabar, ela vai receber null, que uma string promete não ter.
Como consertar: use string? nome = Console.ReadLine(); e trate o null com is null, ou troque por um valor: string nome = Console.ReadLine() ?? "";.
warning CS8602: Desreferência de uma referência possivelmente nula.
O que significa: você usou um ponto (nome.Length, nome.Trim()) numa variável que pode ser null. Se ela for, o programa quebra com NullReferenceException nessa linha.
Como consertar: confira antes (if (nome is not null)), ou garanta um valor na leitura com ?? "".
warning CS8604: Possível argumento de referência nula para o parâmetro 's' em 'int int.Parse(string s)'.
O que significa: o int.Parse(Console.ReadLine()) passa um possível null para um método que não aceita null.
Como consertar: use int.TryParse(texto, out int n), que aceita null (e devolve false).
error CS0029: Não é possível converter implicitamente tipo "string" em "int"
O que significa: você escreveu int idade = Console.ReadLine();. O ReadLine devolve texto, e texto não vira número sozinho.
Como consertar: leia numa string? e converta com int.TryParse.
Unhandled exception. System.FormatException: The input string 'vinte' was not in a correct format.
O que significa: o int.Parse (ou decimal.Parse) recebeu um texto que não é número, e o programa terminou com o código 134.
Como consertar: troque por TryParse num if, e diga ao usuário o que deu errado (ou pergunte de novo).
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
O que significa: a entrada acabou (Ctrl+D, ou o fim do arquivo do <), o ReadLine devolveu null, e o programa usou esse null com um ponto. Era o que os avisos CS8600 e CS8602 diziam.
Como consertar: não ignore os avisos de nulo: siga a seção 3.
3.50 virou 350)
O que significa: no pt-BR, o ponto é separador de milhar, e o decimal.TryParse o ignora sem reclamar.
Como consertar: peça o formato na pergunta ("Preço (ex.: 12,90): "). Para dados de arquivos, use CultureInfo.InvariantCulture (aula Cultura).
O que significa: provavelmente ele está parado num ReadLine, esperando você digitar, e faltou um Console.Write com a pergunta antes.
Como consertar: sempre escreva a pergunta antes de ler. Para sair de um programa que espera entrada, aperte Ctrl+D (fim da entrada) ou Ctrl+C (interromper).
Referência rápida
| Escrita | O que faz |
|---|---|
Console.Write("Nome: "); | Mostra a pergunta e deixa o cursor na mesma linha |
string? s = Console.ReadLine(); | Lê uma linha (sem o Enter); null se a entrada acabou |
string s = Console.ReadLine() ?? ""; | Lê, trocando o null por texto vazio |
if (s is null) | Confere se a entrada acabou |
s.Trim() | Tira os espaços do começo e do fim |
string.IsNullOrWhiteSpace(s) | Nulo, vazio ou só espaços? |
int.TryParse(s, out int n) | Converte para inteiro; true se deu certo |
decimal.TryParse(s, out decimal d) | Converte para decimal, com a vírgula do pt-BR |
while (true) { … ReadLine … break; } | Lê várias linhas até uma condição |
dotnet run prog.cs < arquivo.txt | Manda as linhas do arquivo como entrada |
| Ctrl+D (Linux, macOS) / Ctrl+Z e Enter (Windows) | Fim da entrada: o ReadLine devolve null |
Exercícios
1. O tipo certo
Complete o tipo da variável para não ter nenhum aviso:
2. Sem null
Complete para trocar o null por um texto vazio:
3. Converter sem quebrar
Complete o método que converte texto em int sem lançar exceção:
4. Quando o Console.ReadLine() devolve null?
5. No notebook da Ana (pt-BR), decimal.TryParse("3.50", out decimal d) deixa d valendo…
6. A pessoa digitou dez e o programa usa int.Parse(texto). O que acontece?
Missão final: a média sem avisos
Missão: o programa lê duas notas e mostra a média. Ele funciona com a entrada desta caixa (7,5 e 9), mas compila com dois avisos CS8604 e quebraria com uma nota digitada errado. Reescreva a leitura com decimal.TryParse: se as duas notas forem válidas, mostre Média: 8,25; se não, mostre Nota inválida.. A missão exige zero avisos.
Primeira nota: Segunda nota: Média: 8,25
Console.Write("Primeira nota: ");
decimal nota1 = decimal.Parse(Console.ReadLine());
Console.Write("Segunda nota: ");
decimal nota2 = decimal.Parse(Console.ReadLine());
Console.WriteLine($"Média: {(nota1 + nota2) / 2}");
Console.Write("Primeira nota: ");
string? texto1 = Console.ReadLine();
Console.Write("Segunda nota: ");
string? texto2 = Console.ReadLine();
if (decimal.TryParse(texto1, out decimal nota1) && decimal.TryParse(texto2, out decimal nota2))
{
Console.WriteLine($"Média: {(nota1 + nota2) / 2}");
}
else
{
Console.WriteLine("Nota inválida.");
}
Na solução, as duas leituras vêm primeiro e as duas conversões ficam juntas no if, ligadas por && ("e"): a média só é calculada se as duas derem certo. Experimente mudar a entrada da caixa para 7.5 e 9: com o ponto, a primeira nota vira 75, e a média, 42. É a pegadinha da seção 5.
Resumo
Console.ReadLine()para o programa, espera o Enter e devolve a linha digitada como texto. Escreva a pergunta antes comConsole.Write.- Ele devolve
string?: valenullquando a entrada acaba (Ctrl+D, ou o fim de um arquivo mandado com<). Uma linha vazia é"", nãonull. - Os avisos
CS8600,CS8602eCS8604avisam de umNullReferenceExceptionreal. Trate onullcomis null,?? ""oustring.IsNullOrWhiteSpace; não os cale com!. - Para números, use
int.TryParseedecimal.TryParsenumif. OParsequebra o programa comFormatExceptionquando a pessoa digita errado. - No pt-BR, a vírgula é a casa decimal e o ponto é o milhar:
3.50vira 350 sem erro nenhum. Diga o formato na pergunta. - Para várias respostas, leia num laço até uma linha vazia ou até o
nulldo fim da entrada.