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::getline para ler o nome completo e a cidade.
  • Use std::cin para ler a idade e a altura.
  • Use std::cin.ignore() para limpar o buffer antes de ler a cidade.
  • Use std::format para 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

  1. Incluímos <format> para std::format e <limits> para std::numeric_limits.
  2. Lemos o nome completo com std::getline, que captura espaços.
  3. Lemos a idade e a altura com std::cin >>, que ignoram espaços e leem até o caractere não numérico.
  4. Após a leitura da altura, o caractere \n permanece no buffer. Usamos std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); para descartar tudo até a nova linha.
  5. Lemos a cidade com std::getline.
  6. Usamos std::format para montar a string final, com {:.2f} para formatar a altura com duas casas decimais e espaços fixos para alinhar os rótulos.
  7. 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 de getline: a leitura da cidade resulta em string vazia, pois o \n remanescente é consumido por getline.
  • Esquecer de incluir <format>: std::format não estará disponível.
  • Usar std::endl dentro do std::format: endl é um manipulador de fluxo, não faz parte da string de formato. Use \n.
  • Não verificar se std::format está 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