C++: Entrada e Saída em Profundidade
Última atualização: 2026-08-26
Na Aula 03 usamos brevemente
cinecout, mas isso foi apenas a ponta do iceberg.Em cenários reais, você precisa lidar com strings com espaços, controlar casas decimais e tornar a saída mais apresentável...
Nesta aula, vamos mergulhar profundamente em todas as capacidades de
cinecout.
1. Uso Avançado de cout
(1) 1.1 Caracteres de Escape
Alguns caracteres não podem ser digitados diretamente (como nova linha, Tab), então precisam ser representados usando caracteres de escape.
| Caractere de Escape | Significado | Exemplo |
|---|---|---|
\n |
Nova linha | std::cout << "Hello\nWorld"; |
\t |
Tab | std::cout << "Name:\tMOTO"; |
\\ |
Barra invertida | std::cout << "C:\\Users\\MOTO"; |
\" |
Aspas duplas | std::cout << "He said \"Hi\""; |
\0 |
Caractere nulo (terminador de string) | (Coberto mais tarde) |
Exemplo: Saída formatada com caracteres de escape (Dificuldade ⭐)
▶ Exemplo 2: Prática Básica de Programação (Dificuldade ⭐)
#include <iostream>
int main() {
std::cout << "========== Report Card ==========\n";
std::cout << "Name: \tMOTO\n";
std::cout << "Age: \t35\n";
std::cout << "Score: \t92.5\n";
std::cout << "===================\n";
return 0;
}
Saída:
========== Report Card ==========
Name: MOTO
Age: 35
Score: 92.5
===================
(2) 1.2 endl vs \n
| Notação | Efeito | Desempenho |
|---|---|---|
std::endl |
Emite nova linha + descarrega o buffer | Lento (descarrega toda vez) |
"\n" |
Apenas emite nova linha | Rápido (recomendado) |
💡 Recomendação: A menos que você precise explicitamente descarregar o buffer, use "\n" em vez de std::endl.
std::cout << "Hello" << std::endl; // Nova linha + descarga (lento)
std::cout << "Hello\n"; // Apenas nova linha (rápido, recomendado)
2. Saída Formatada com cout
(1) 2.1 Controlando Casas Decimais
Por padrão, cout escolhe automaticamente o formato para saída de ponto flutuante (ex: 3.14159 ou 3.14). Mas às vezes você precisa de um número fixo de casas decimais (ex: exibir um preço como R$19,99).
Requer #include <iomanip>
#include <iostream>
#include <iomanip> // Deve incluir este cabeçalho
int main() {
double pi = 3.141592653589793;
std::cout << "Default: " << pi << std::endl;
// Casas decimais fixas (2 dígitos)
std::cout << std::fixed << std::setprecision(2);
std::cout << "2 decimal places: " << pi << std::endl;
// Restaurar padrão
std::cout.unsetf(std::ios::fixed);
std::cout << std::setprecision(6); // Restaurar precisão padrão
std::cout << "Restored default: " << pi << std::endl;
return 0;
}
💡 Pontos-chave:
std::fixed— Usar formato decimal fixo (sem notação científica)std::setprecision(n)— Definir precisão (quando combinado comfixed, isso significa n casas decimais)
(2) 2.2 Controlando Largura de Saída (Alinhamento)
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::left; // Alinhar à esquerda
std::cout << std::setw(10) << "Name" << std::setw(5) << "Age" << std::endl;
std::cout << std::setw(10) << "MOTO" << std::setw(5) << 35 << std::endl;
std::cout << std::setw(10) << "Alice" << std::setw(5) << 20 << std::endl;
return 0;
}
| Manipulador | Efeito |
|---|---|
std::setw(n) |
Definir a largura da próxima saída para n caracteres |
std::left |
Alinhar à esquerda |
std::right |
Alinhar à direita (padrão) |
std::setfill(c) |
Definir o caractere de preenchimento (padrão é espaço) |
3. Uso Avançado de cin
(1) 3.1 Armadilha do cin: Para nos Espaços
cin >> para de ler uma string quando encontra um espaço!
#include <iostream>
#include <string>
int main() {
std::string name;
std::cout << "Please enter your full name (e.g., John Smith): ";
std::cin >> name;
std::cout << "Hello," << name << "!" << std::endl;
return 0;
}
Resultado da execução:
Please enter your full name (e.g., John Smith): John Smith
Hello,John! ← Apenas leu "John", "Smith" foi descartado
(2) 3.2 Usando getline para Ler uma Linha Inteira
Para ler uma linha inteira incluindo espaços, use std::getline().
#include <iostream>
#include <string>
int main() {
std::string fullName;
std::cout << "Please enter your full name: ";
std::getline(std::cin, fullName); // Lê linha inteira (incluindo espaços)
std::cout << "Hello," << fullName << "!" << std::endl;
return 0;
}
Resultado da execução:
Please enter your full name: John Smith
Hello,John Smith! ← Leitura completa
(3) 3.3 A Armadilha de Misturar cin e getline
Problema:
#include <iostream>
#include <string>
int main() {
int age;
std::string name;
std::cout << "Please enter your age: ";
std::cin >> age;
std::cout << "Please enter your name: ";
std::getline(std::cin, name); // ❌ Esta linha é ignorada!
std::cout << "Age: " << age << ",Name: " << name << std::endl;
return 0;
}
Razão: Após cin >> age ler o inteiro, um caractere de nova linha \n permanece no buffer de entrada. Quando getline vê \n, ele acha que o usuário digitou uma linha vazia e retorna imediatamente.
Solução: Use cin.ignore() para descartar o caractere de nova linha
#include <iostream>
#include <string>
int main() {
int age;
std::string name;
std::cout << "Please enter your age: ";
std::cin >> age;
std::cin.ignore(); // Descarta o caractere de nova linha
std::cout << "Please enter your name: ";
std::getline(std::cin, name); // ✅ Agora lê corretamente
std::cout << "Age: " << age << ",Name: " << name << std::endl;
return 0;
}
💡 Regra de ouro: Se você usar cin >> primeiro e depois getline, lembre-se de adicionar cin.ignore().
4. Prática: Formulário de Cadastro de Usuário
▶ Exemplo 1: Cadastro de Informações do Usuário (Dificuldade ⭐⭐)
#include <iostream>
#include <string>
#include <iomanip>
int main() {
std::string name, address;
int age;
double salary;
std::cout << "========== User Information Registration ==========\n";
std::cout << "Please enter your name: ";
std::getline(std::cin, name);
std::cout << "Please enter your age: ";
std::cin >> age;
std::cin.ignore(); // Descarta caractere de nova linha
std::cout << "Please enter your address: ";
std::getline(std::cin, address);
std::cout << "Please enter your monthly salary: ";
std::cin >> salary;
// Exibir formulário de cadastro
std::cout << "\n========== Registration Result ==========\n";
std::cout << "Name: " << name << std::endl;
std::cout << "Age: " << age << " years old" << std::endl;
std::cout << "Address: " << address << std::endl;
std::cout << std::fixed << std::setprecision(2);
std::cout << "Monthly salary: " << salary << " yuan" << std::endl;
std::cout << "==============================\n";
return 0;
}
Saída:
========== User Information Registration ==========
Please enter your name:
Please enter your age:
Please enter your address:
Please enter your monthly salary:
========== Registration Result ==========
Name:
Age: years old
Address:
Monthly salary: yuan
=============================
Resultado da execução:
========== User Information Registration ==========
Please enter your name: MOTO
Please enter your age: 35
Please enter your address: Meijia Vocational College, Xiaogan, Hubei
Please enter your monthly salary: 15000
========== Registration Result ==========
Name: MOTO
Age: 35 years old
Address: Meijia Vocational College, Xiaogan, Hubei
Monthly salary: 15000.00 yuan
=============================
5. Introdução à E/S de Arquivo (Opcional)
Além de ler do teclado e escrever na tela, C++ também pode ler dados de arquivos e escrever dados em arquivos.
(1) 5.1 Escrevendo em um Arquivo
#include <iostream>
#include <fstream> // Cabeçalho de fluxo de arquivo
int main() {
std::ofstream outFile("output.txt"); // Cria fluxo de arquivo de saída
if (!outFile) {
std::cout << "Cannot open file!" << std::endl;
return 1;
}
outFile << "Hello, File!" << std::endl;
outFile << "This is the content written to the file." << std::endl;
outFile.close(); // Fecha o arquivo
std::cout << "Write successful!" << std::endl;
return 0;
}
Após executar, um arquivo output.txt será gerado no diretório do programa.
(2) 5.2 Lendo de um Arquivo
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::ifstream inFile("output.txt"); // Cria fluxo de arquivo de entrada
if (!inFile) {
std::cout << "Cannot open file!" << std::endl;
return 1;
}
std::string line;
while (std::getline(inFile, line)) {
std::cout << "Read: " << line << std::endl;
}
inFile.close();
return 0;
}
💡 Dica: E/S de arquivo é um tópico grande — esta é apenas uma breve introdução. Haverá uma aula dedicada cobrindo-o em profundidade mais tarde.
❓ Perguntas Frequentes
P: Por que meu programa exibe caracteres chineses corrompidos? R: Este é um problema de codificação chinesa no console do Windows. Você pode adicionar
system("chcp 65001");no início do seu programa para mudar para codificação UTF-8, ou mudar a fonte do console para "NSimSun". macOS/Linux geralmente não tem esse problema. P: Por que cin e cout precisam de std::? Posso omitir? R:cin/coutsão definidos no namespacestd. Você pode usarusing namespace std;para evitar escreverstd::, mas não é recomendado — pode causar conflitos de nomenclatura. É recomendado sempre escreverstd::cin,std::cout. P: Como limpo a tela? R: Windows:system("cls");, macOS/Linux:system("clear");. Mas esta abordagem não é portável e não é recomendada em produção — apenas para uso temporário durante o aprendizado. P: Por que getline consegue ler strings mas não int? R:getlinesó pode ler strings. Para ler inteiros, usecin >>. Se você quer ler uma linha inteira e depois analisá-la como inteiro, usestd::stoi(line)para converter uma string em inteiro.
▶ Exemplo 3: Saída Formatada (Dificuldade ⭐)
#include <iostream>
#include <iomanip>
int main() {
double price = 19.99;
int quantity = 5;
std::cout << "Unit price: " << std::fixed << std::setprecision(2) << price << std::endl;
std::cout << "Quantity: " << std::setw(5) << quantity << std::endl;
std::cout << "Total: " << price * quantity << std::endl;
return 0;
}
Saída:
Unit price: 19.99
Quantity: 5
Total: 99.95
std::fixed + std::setprecision(2) mantém 2 casas decimais; std::setw(5) define a largura.
coutusa caracteres de escape (\n,\t) para controlar formatação- Use
std::fixed+std::setprecision(n)para controlar casas decimais - Use
std::setw(n)para controlar largura de saída (alinhamento) cin >>para de ler strings nos espaços; usegetlinepara ler linhas inteiras- Ao misturar
cin >>egetline, lembre-se de adicionarcin.ignore()para descartar o caractere de nova linha - E/S de arquivo requer
#include <fstream>
📖 Resumo
- std::cin: Fluxo de entrada padrão
- std::cout: Fluxo de saída padrão
- std::cerr: Fluxo de erro padrão (sem buffer)
- Formatação:
std::setw,std::setprecision, etc.
📝 Exercícios
- Básico (Dificuldade ⭐): Escreva um programa que exiba uma tabuada (1-9) no seguinte formato:
1 x 1 = 1
1 x 2 = 2 2 x 2 = 4
1 x 3 = 3 2 x 3 = 6 3 x 3 = 9
...
(Dica: use \t para alinhamento e loops aninhados)
- Intermediário (Dificuldade ⭐⭐): Escreva um programa que permita ao usuário inserir:
- Nome do produto (pode conter espaços, ex: "iPhone 15 Pro")
- Preço unitário
- Quantidade
O programa calcula o total e exibe formatado:
========== Shopping Receipt ==========
Product name: iPhone 15 Pro
Unit price: 6999.00 yuan
Quantity: 2
Total: 13998.00 yuan
==============================
- Desafio (Dificuldade ⭐⭐⭐): Escreva um programa que implemente um "cadastro de contato":
- Deixe o usuário inserir informações de 3 contatos (nome, telefone, relacionamento)
- Escreva as informações em um arquivo
contacts.txt - Depois leia do arquivo e exiba
(Dica: use ofstream para escrever, ifstream para ler)
- cout usa << para saída, suporta caracteres de escape (\n, \t)
- Saída formatada: fixed/setprecision para decimais, setw para largura
- cin usa >> para entrada, para nos espaços
- getline lê linha inteira de string; adicione cin.ignore() ao misturar com cin
- E/S de arquivo: ofstream para escrever, ifstream para ler
6. 🚀 Próximo Passo
Agora que você aprendeu entrada e saída, a seguir vamos aprender instruções condicionais (if-else) (Aula 06) — permitindo que programas tomem decisões e executem código diferente baseado em diferentes condições.