Desafio C++
Formulário com validação e std::format
Enunciado
Crie um programa que leia os seguintes dados de um usuário: nome completo (linha), idade (int), altura (double) e cidade (linha). Após a leitura, exiba uma ficha formatada usando std::format com as informações alinhadas e a altura com duas casas decimais. A saída deve ser exatamente:
Nome: [nome]
Idade: [idade] anos
Altura: [altura] m
Cidade: [cidade]
Considere que a leitura da idade e altura pode deixar o caractere de nova linha no buffer, então use std::cin.ignore() antes de ler a cidade.
Requisitos
- Use
std::getlinepara ler o nome completo e a cidade. - Use
std::cinpara ler a idade e a altura. - Use
std::cin.ignore()para limpar o buffer antes de ler a cidade. - Use
std::formatpara montar a saída formatada com alinhamento e precisão. - A saída deve corresponder exatamente ao formato especificado.
Código inicial
#include <iostream>
#include <string>
#include <format>
#include <limits>
int main() {
// Seu código aqui
return 0;
}
Saída esperada
Nome: Ana Paula Souza
Idade: 28 anos
Altura: 1.65 m
Cidade: São Paulo
Ver dica
Para alinhar à esquerda com largura fixa, use {:<10} no std::format. Para a altura, use {:.2f}. Lembre-se de limpar o buffer após ler a altura com std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');.
Mostrar solução
#include <iostream>
#include <string>
#include <format>
#include <limits>
int main() {
std::string nome;
std::cout << "Digite o nome completo: ";
std::getline(std::cin, nome);
int idade;
std::cout << "Digite a idade: ";
std::cin >> idade;
double altura;
std::cout << "Digite a altura (m): ";
std::cin >> altura;
// Limpa o buffer de entrada para remover o '\n' deixado por cin >>
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::string cidade;
std::cout << "Digite a cidade: ";
std::getline(std::cin, cidade);
// Monta a saída formatada com std::format
std::string ficha = std::format(
"Nome: {}\n"
"Idade: {} anos\n"
"Altura: {:.2f} m\n"
"Cidade: {}",
nome, idade, altura, cidade
);
std::cout << ficha << std::endl;
return 0;
}
Passo a passo
- Incluímos
<format>parastd::formate<limits>parastd::numeric_limits. - Lemos o nome completo com
std::getline, que captura espaços. - Lemos a idade e a altura com
std::cin >>, que ignoram espaços e leem até o caractere não numérico. - Após a leitura da altura, o caractere
\npermanece no buffer. Usamosstd::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');para descartar tudo até a nova linha. - Lemos a cidade com
std::getline. - Usamos
std::formatpara montar a string final, com{:.2f}para formatar a altura com duas casas decimais e espaços fixos para alinhar os rótulos. - Imprimimos a ficha com
std::cout.
Por que funciona
std::getline lê a linha inteira, permitindo nomes e cidades com espaços. A limpeza do buffer com ignore garante que a leitura subsequente com getline não seja pulada. std::format oferece uma sintaxe segura e expressiva, com verificação de tipos em tempo de compilação, evitando erros comuns de printf. O alinhamento é feito manualmente com espaços na string de formato, mas também poderia usar especificadores de largura como {:<10}.
Erros comuns
- Não limpar o buffer após
cin >>antes degetline: a leitura da cidade resulta em string vazia, pois o\nremanescente é consumido porgetline. - Esquecer de incluir
<format>:std::formatnão estará disponível. - Usar
std::endldentro dostd::format:endlé um manipulador de fluxo, não faz parte da string de formato. Use\n. - Não verificar se
std::formatestá disponível no compilador (requer C++20).
Outra forma de resolver
Sem std::format, use std::cout com manipuladores:
std::cout << "Nome: " << nome << "\n"
<< "Idade: " << idade << " anos\n"
<< std::fixed << std::setprecision(2)
<< "Altura: " << altura << " m\n"
<< "Cidade: " << cidade << std::endl;
É preferível quando se deseja compatibilidade com C++17 ou anterior.
Saída esperada
Nome: Ana Paula Souza
Idade: 28 anos
Altura: 1.65 m
Cidade: São Paulo