C++ Entrada com cin
Até agora, todos os seus programas mostravam sempre a mesma coisa: os valores estavam escritos no próprio código. Um programa de verdade conversa com quem usa: pergunta a idade, o nome, o preço de um produto, e responde de acordo. Em C++, o jeito mais simples de ler o que a pessoa digita é o std::cin. Nesta aula você vai ler números, palavras e vários valores de uma vez, e vai ver o que acontece quando a pessoa digita algo inesperado.
- Como ler um valor do teclado com
std::cin >> variavel;. - Como o
cinusa o tipo da variável para decidir o que ler. - Como ler vários valores numa linha só:
std::cin >> a >> b;. - Por que o
cinlê só a primeira palavra de "Ana Maria". - O que acontece quando a pessoa digita uma letra onde se espera um número (e por que a vírgula no preço dá errado).
- Como testar programas que leem do teclado, no terminal e no editor do guia.
Todos os programas desta aula foram compilados com o g++ 15.2 na máquina fictícia da Ana (usuária ana, computador notebook), na pasta ~/cpp, com o comando padrão do guia: g++ -std=c++23 -Wall -Wextra arquivo.cpp -o programa.
A ideia: a esteira do caixa do mercado
Pense na esteira do caixa do supermercado. O cliente vai colocando as compras na esteira, separadas por aquelas barrinhas divisórias. A operadora do caixa pega um produto de cada vez, do começo da esteira, e não se importa com quantas divisórias existem entre um produto e outro.
O cin funciona assim:
- Tudo o que você digita vai para uma esteira de caracteres (os programadores chamam de buffer, "área de espera"). Nada chega ao programa antes de você apertar Enter.
- Os espaços e os Enter são as barrinhas divisórias.
- Cada
>>pega um pedaço do começo da esteira e o guarda numa variável. O que sobrou continua na esteira, esperando o próximo>>.
O nome cin vem de character input, "entrada de caracteres", e é o irmão do cout (character output, veja Saída com cout). Os dois moram na biblioteca <iostream>.
1. Ler um número
#include <iostream>
int main() {
int idade = 0;
std::cout << "Quantos anos você tem? ";
std::cin >> idade;
std::cout << "Daqui a 10 anos você terá " << idade + 10 << " anos.\n";
}
- int idade = 0;
- Cria a variável que vai receber o que for digitado. Começar com 0 é uma boa prática: a variável nunca fica com lixo (veja Variáveis).
- std::cout << "Quantos anos você tem? ";
- A pergunta. Sem ela, o programa ficaria parado esperando, e a pessoa não saberia o que digitar. Repare que não há
\n: assim o cursor fica na mesma linha, logo depois da pergunta. - std::cin
- A entrada padrão: normalmente, o teclado.
- >>
- O operador de extração ("tirar de dentro"). Pense numa seta mostrando para onde o valor vai: do
cinpara a variável. Nocouta seta é ao contrário,<<, porque o valor vai da variável para a tela. - idade
- Onde guardar o valor. O programa para nesta linha e espera a pessoa digitar e apertar Enter.
Rodando no terminal, a Ana digita 29 e aperta Enter:
$ g++ -std=c++23 -Wall -Wextra idade.cpp -o idade $ ./idade Quantos anos você tem? 29 « o 29 foi digitado pela Ana, seguido de Enter Daqui a 10 anos você terá 39 anos.
O 29 aparece na tela porque o terminal mostra o que você digita (isso se chama eco). O Enter que a Ana apertou também é eco: é por isso que a resposta começa na linha de baixo, mesmo sem \n antes dela.
Testar sem digitar: o printf com |
Digitar a mesma coisa toda vez que você testa cansa. No terminal, dá para "digitar" pelo programa com o comando printf e uma barra vertical | (o pipe, "cano"), que liga a saída de um comando à entrada do outro:
$ printf '29\n' | ./idade Quantos anos você tem? Daqui a 10 anos você terá 39 anos.
- printf '29\n'
- Escreve
29seguido de uma quebra de linha (o\nfaz o papel do Enter). - |
- Em vez de ir para a tela, esse texto vai para a entrada do
./idade: ocino lê como se fosse digitado.
A resposta ficou grudada na pergunta porque, desta vez, ninguém digitou: não houve eco do 29 nem do Enter. O programa é o mesmo; só a tela fica diferente. O Guia Bash tem uma aula inteira sobre o |; aqui basta saber que ele economiza digitação. Vamos usar as duas formas nesta aula.
2. O tipo da variável decide o que é lido
O >> olha o tipo da variável que vai receber o valor e lê do jeito certo para aquele tipo:
| Tipo da variável | O que o >> pega da esteira | Digitado → guardado |
|---|---|---|
int | Sinal (opcional) e algarismos. Para no primeiro caractere que não é algarismo. | 29 → 29 |
double | Algarismos, com ponto decimal. | 12.50 → 12.5 |
char | Um caractere (que não seja espaço). | sim → 's' |
std::string | Uma palavra: tudo até o próximo espaço ou Enter. | Ana Maria → "Ana" |
Um double, para calcular um desconto:
#include <iostream>
int main() {
double preco = 0;
std::cout << "Preço: ";
std::cin >> preco;
std::cout << "Com 10% de desconto: " << preco * 0.9 << '\n';
}
$ g++ -std=c++23 -Wall -Wextra preco.cpp -o preco $ printf '12.50\n' | ./preco Preço: Com 10% de desconto: 11.25
E um char, para uma resposta de uma letra. Repare que a Ana digitou a palavra inteira sim, mas o char só guarda um caractere:
#include <iostream>
int main() {
char resposta = '?';
std::cout << "Continuar (s/n)? ";
std::cin >> resposta;
std::cout << "Você respondeu: " << resposta << '\n';
}
$ g++ -std=c++23 -Wall -Wextra letra.cpp -o letra $ ./letra Continuar (s/n)? sim Você respondeu: s « só o 's'; o "im" ficou na esteira e foi descartado no fim do programa
3. Ler vários valores
Você pode encadear vários >> no mesmo cin, do mesmo jeito que encadeia vários << no cout. Eles são lidos da esquerda para a direita:
#include <iostream>
int main() {
int a = 0;
int b = 0;
std::cout << "Digite dois números: ";
std::cin >> a >> b;
std::cout << a << " + " << b << " = " << a + b << '\n';
}
std::cin >> a >> b; é o mesmo que std::cin >> a; seguido de std::cin >> b;. E, como espaços e Enter são todos "divisórias", a pessoa pode digitar os números na mesma linha ou em linhas separadas:
$ g++ -std=c++23 -Wall -Wextra soma.cpp -o soma $ ./soma Digite dois números: 3 « a Ana digitou 3 e Enter: o cin leu o 3 e continua esperando o b 4 3 + 4 = 7 $ ./soma Digite dois números: 10 20 30 « três números para duas variáveis 10 + 20 = 30 « o 30 sobrou na esteira e ninguém leu
Os valores podem ter tipos diferentes. Cada >> lê do jeito do tipo da sua variável:
#include <iostream>
#include <string>
int main() {
std::string produto;
int quantidade = 0;
double preco = 0;
std::cout << "Produto, quantidade e preço: ";
std::cin >> produto >> quantidade >> preco;
std::cout << quantidade << "x " << produto << " = R$ " << quantidade * preco << '\n';
}
$ g++ -std=c++23 -Wall -Wextra cadastro.cpp -o cadastro $ ./cadastro Produto, quantidade e preço: café 2 18.90 2x café = R$ 37.8
O #include <string> traz o std::string, o tipo para textos (aula Strings). O resultado 37.8 aparece sem o zero final porque o cout esconde zeros que não mudam o valor; para mostrar 37.80, veja Formatar com iomanip.
Experimente: esta caixa já vem com a entrada 8 6, como se alguém tivesse digitado (é o mesmo papel do printf '8 6\n' | no terminal). Rode, depois acrescente a subtração e a multiplicação na saída.
#include <iostream>
int main() {
int a = 0;
int b = 0;
std::cin >> a >> b;
std::cout << "Soma: " << a + b << '\n';
}
4. Ler texto: o cin para no espaço
Com um std::string, o >> lê uma palavra. Para o cin, "palavra" é tudo até o primeiro espaço, tab ou Enter. Isso surpreende quem tenta ler um nome completo:
#include <iostream>
#include <string>
int main() {
std::string nome;
std::cout << "Seu nome: ";
std::cin >> nome;
std::cout << "Olá, " << nome << "!\n";
}
$ g++ -std=c++23 -Wall -Wextra nome.cpp -o nome $ ./nome Seu nome: Ana Maria Olá, Ana! « cadê a Maria? $ printf 'Ana Maria\n' | ./nome Seu nome: Olá, Ana!
A "Maria" não sumiu: ela ficou na esteira, esperando outro >>. Como este programa não lê mais nada, ela foi descartada quando o programa terminou. Para ver a Maria, leia duas vezes:
#include <iostream>
#include <string>
int main() {
std::string nome;
std::string sobrenome;
std::cin >> nome;
std::cin >> sobrenome;
std::cout << "[" << nome << "] [" << sobrenome << "]\n";
}
$ g++ -std=c++23 -Wall -Wextra nome2.cpp -o nome2 $ printf 'Ana Maria\n' | ./nome2 [Ana] [Maria] « o segundo >> pegou o que sobrou na esteira $ printf ' Ana\n\n\n Maria \n' | ./nome2 [Ana] [Maria] « espaços e linhas vazias no caminho são pulados
Os colchetes mostram exatamente onde cada texto começa e termina: o >> pula os espaços e os Enter antes da palavra, e não guarda o espaço depois dela. Isso também vale para números: " 29" é lido como 29.
Esse "pular" tem um efeito curioso no terminal: se a pessoa só apertar Enter, o programa continua esperando, porque ainda não chegou nenhuma palavra:
$ ./nome
Seu nome: « a Ana apertou Enter
« e Enter de novo: o cin continua esperando uma palavra
Ana
Olá, Ana!
Para ler "Ana Maria" (ou "pão de queijo") inteiro numa variável, existe o std::getline, que lê até o Enter, com espaços e tudo. Ele tem aula própria: Ler uma Linha (getline). O >> é o certo para números e palavras soltas.
5. Quando a pessoa digita outra coisa
O cin confia que a pessoa vai digitar o que foi pedido. Quando ela não digita, o resultado pode ser estranho, e nenhuma mensagem de erro aparece. Conhecer esses casos evita muita confusão.
Uma letra onde se espera um número
O mesmo idade.cpp do começo. Desta vez, a Ana digita abc:
$ ./idade Quantos anos você tem? abc Daqui a 10 anos você terá 10 anos. « a idade virou 0! $ echo $? 0 « e o programa terminou como se tudo estivesse bem
O que aconteceu, passo a passo:
- O
>>foi ler uminte encontrou a letraa, que não pode começar um número. - A leitura falhou. Quando isso acontece, o C++ (desde o C++11) coloca 0 na variável.
- O
abccontinua na esteira: o>>não tira o que não conseguiu ler. - O
cinentra em estado de falha: a partir daí, todas as próximas leituras são ignoradas, até alguém "consertar" ocin. - O programa continua normalmente e calcula 0 + 10.
O passo 4 é o mais perigoso. Veja um programa que lê dois números:
#include <iostream>
int main() {
int idade = -1;
int ano = -1;
std::cout << "Idade e ano de nascimento: ";
std::cin >> idade >> ano;
std::cout << "idade = " << idade << ", ano = " << ano << '\n';
}
$ g++ -std=c++23 -Wall -Wextra falha.cpp -o falha $ ./falha Idade e ano de nascimento: 29 2000 idade = 29, ano = 2000 $ ./falha Idade e ano de nascimento: abc 2000 idade = 0, ano = -1 « a idade virou 0; o ano nem foi lido
As variáveis começaram com −1 justamente para mostrar o que mudou. A idade virou 0 (falhou). O ano continuou −1: depois da falha, o cin nem tentou ler o 2000, mesmo ele estando ali na esteira.
Um número "com sobra"
Se o começo do que foi digitado é um número válido, o >> lê até onde der e deixa o resto na esteira:
$ ./idade Quantos anos você tem? 12abc Daqui a 10 anos você terá 22 anos. « leu o 12 e parou no 'a' $ ./idade Quantos anos você tem? 3.7 Daqui a 10 anos você terá 13 anos. « int não tem ponto: leu o 3 e parou no '.'
A vírgula no preço
No Brasil escrevemos 12,50. O cin espera o formato americano, com ponto: 12.50. A vírgula não é um erro para ele, é só "o fim do número":
$ ./preco Preço: 12,50 Com 10% de desconto: 10.8 « leu só o 12 (10% de desconto de 12 = 10.8)
Esse engano é traiçoeiro porque o resultado parece certo. Em programas para outras pessoas, diga na pergunta que é para usar ponto ("Preço (use ponto, ex.: 12.50): "), ou leia como texto e troque a vírgula (assunto de Texto ↔ Número).
Nesta aula, os programas supõem que a pessoa digita o que foi pedido. Programas de verdade precisam conferir se a leitura deu certo e pedir de novo quando não deu. Isso exige if e laços de repetição, e tem uma aula própria: Validar a Entrada.
6. cin no editor do guia
As caixas "Experimente" rodam o programa no seu navegador. Quando o programa usa std::cin, a entrada pode chegar de duas formas:
- Entrada preparada: a caixa já vem com o texto que o programa vai ler, como na caixa da seção 3. É o mesmo que
printf '…' | ./programano terminal: o que foi "digitado" não aparece na saída, então a resposta pode ficar grudada na pergunta. Isso é normal. - Você digita: sem entrada preparada, o programa pode pedir e você digita no terminal da caixa, como no terminal de verdade.
A aula O Editor do Guia mostra os detalhes de como o editor lida com a entrada.
Experimente: a entrada preparada é Ana Maria 29. Rode e veja o que vai para cada variável: a idade sai 0. Por quê? (Dica: qual palavra o segundo >> encontrou na esteira?) Depois troque std::cin >> nome >> idade; por std::cin >> nome >> sobrenome >> idade;, crie a variável sobrenome e mostre-a também.
#include <iostream>
#include <string>
int main() {
std::string nome;
int idade = -1;
std::cin >> nome >> idade;
std::cout << "nome = [" << nome << "]\n";
std::cout << "idade = " << idade << '\n';
}
Formas diferentes: qual usar
| Você quer ler… | Use | Observação |
|---|---|---|
| Um número inteiro | int n = 0; std::cin >> n; | Letra no lugar do número: n vira 0 e o cin falha. |
| Um número com casas decimais | double x = 0; std::cin >> x; | Com ponto: 12.50. A vírgula encerra o número. |
| Uma letra (s/n) | char c = '?'; std::cin >> c; | Pega um caractere; o resto fica na esteira. |
| Uma palavra | std::string p; std::cin >> p; | Para no espaço. |
| Vários valores | std::cin >> a >> b >> c; | Separados por espaço ou Enter. |
| Uma frase inteira | std::getline(std::cin, frase); | Aula getline. |
Quando dá errado
error: no match for ‘operator<<’ (operand types are ‘std::istream’ … and ‘int’)
$ g++ -std=c++23 -Wall -Wextra seta.cpp -o seta
seta.cpp: In function ‘int main()’:
seta.cpp:5:14: error: no match for ‘operator<<’ (operand types are ‘std::istream’ {aka ‘std::basic_istream<char>’} and ‘int’)
5 | std::cin << idade;
| ~~~~~~~~ ^~ ~~~~~
| | |
| | int
| std::istream {aka std::basic_istream<char>}
seta.cpp:5:14: note: there are 30 candidates « seguem mais 234 linhas de "candidatos"
O que aconteceu: a seta está virada. std::cin << idade tenta "mandar a idade para o teclado", o que não existe. O g++ explica: "não há << entre um std::istream (o tipo do cin; input stream, fluxo de entrada) e um int". Depois ele lista dezenas de "candidatos" (outras versões de << que também não servem); pode ignorar, a primeira linha de error já diz tudo.
Como resolver: std::cin >> idade;. Para lembrar: as setas apontam para onde o valor vai. Do cin para a variável: >>. Da variável para o cout: <<.
$ ./idade Quantos anos você tem? abc Daqui a 10 anos você terá 10 anos.
O que aconteceu: a leitura do int falhou. A variável virou 0 e o cin passou a ignorar as próximas leituras. Nada avisa: o código de saída continua 0.
Como resolver: por enquanto, diga claramente na pergunta o que digitar. Na aula Validar a Entrada você vai aprender a detectar a falha e pedir de novo.
$ printf 'pão de queijo 3 2.50\n' | ./cadastro Produto, quantidade e preço: 0x pão = R$ 0
O que aconteceu: o >> do produto leu só pão. O próximo >> tentou ler a quantidade e encontrou de: falhou, virou 0, e o preco nem foi lido (continuou com o 0 inicial).
Como resolver: para nomes com espaço, leia a linha inteira com getline, ou peça o nome numa pergunta separada.
O que aconteceu: provavelmente ele está parado num std::cin >>, esperando você digitar, e você esqueceu de mostrar uma pergunta antes. Ou você apertou só Enter, e o >> continua esperando um valor de verdade.
Como resolver: digite o valor e aperte Enter. Para desistir, aperte Ctrl+C. No código, coloque sempre um std::cout com a pergunta antes de cada leitura.
Referência
| Código | O que faz |
|---|---|
#include <iostream> | Traz std::cin e std::cout. |
std::cin >> x; | Lê um valor do tipo de x e guarda em x. Pula espaços e Enter antes do valor. |
std::cin >> a >> b; | Lê a, depois b. |
| Leitura que falha | Número vira 0; o que não foi lido fica na esteira; as próximas leituras são ignoradas. |
| Valores a mais | Ficam na esteira para o próximo >> (ou são descartados no fim do programa). |
printf '29\n' | ./prog | No terminal, "digita" 29 e Enter para o programa. |
Exercícios
1. A seta certa
Complete para ler um valor do teclado e guardar na variável nota:
2. Dois de uma vez
Complete para ler a largura e depois a altura num comando só:
3. Qual biblioteca?
Complete o #include necessário para usar std::cin:
4. A variável é std::string cidade;. A pessoa digita Belo Horizonte. O que fica em cidade depois de std::cin >> cidade;?
5. int x = 5; e a pessoa digita dez para std::cin >> x;. Quanto vale x?
6. double preco = 0; e a pessoa digita 7,90. Quanto vale preco?
Missão final: a calculadora de área
Missão: a entrada preparada traz a largura e o comprimento de um quarto, em metros: 4.5 3. Leia os dois valores com std::cin (em variáveis double) e mostre a área, que é largura × comprimento:
Área: 13.5 m²
#include <iostream>
int main() {
double largura = 0;
double comprimento = 0;
// leia os dois valores aqui
// mostre a área aqui
}
#include <iostream>
int main() {
double largura = 0;
double comprimento = 0;
std::cin >> largura >> comprimento;
std::cout << "Área: " << largura * comprimento << " m²\n";
}
Resumo
std::cin >> variavel;espera a pessoa digitar e apertar Enter, e guarda o valor na variável. A seta aponta para onde o valor vai.- Sempre mostre uma pergunta com
std::coutantes de ler. - O tipo da variável decide o que é lido:
intlê algarismos,doublelê número com ponto,charlê um caractere,std::stringlê uma palavra. - Espaços e Enter separam os valores:
std::cin >> a >> b;aceita3 4ou3Enter4. O que sobra fica na esteira para a próxima leitura. - Para texto, o
>>para no espaço: "Ana Maria" vira "Ana". Para a linha inteira, use getline. - Letra num
int: a variável vira 0, ocinfalha em silêncio e ignora as próximas leituras. Vírgula numdouble: só a parte antes da vírgula é lida. Validar fica para Validar a Entrada. - No terminal,
printf '…\n' | ./programa"digita" por você. No editor do guia, a entrada preparada faz o mesmo papel.