1
0
Fork
You've already forked exercicio-cli-dice
0
Exercício de prática de argumentos de linha de comando. Programação 1, DIMAp, UFRN.
  • C++ 95%
  • CMake 5%
2026年04月14日 16:44:50 -03:00
src Program is finished but not totally tested yet 2026年04月14日 16:44:50 -03:00
tests First commit 2026年04月08日 21:48:51 -03:00
.gitignore First commit 2026年04月08日 21:48:51 -03:00
CMakeLists.txt First commit 2026年04月08日 21:48:51 -03:00
README.md First commit 2026年04月08日 21:48:51 -03:00

Exercício: Simulador de Dados

1. Introdução

Neste exercício proposto, vamos trabalhar o conceito de argumentos de linha de comando (argc / argv). A utilização desse recurso do C/C++ é fundamental para implementarmos uma command line interface (CLI). Esse tipo de interface com usuário, é muito comum em programas Linux que são executados em um emulador de terminal.

Important

Conexão com o projeto passgen: a estrutura de parsing que você implementar aqui — iterar sobre argv, detectar flags com prefixo --, consumir o próximo token como valor numérico e acumular flags booleanas independentes — é exatamente a mesma que será necessária no projeto passgen. Aproveite para criar uma lógica reutilizável.

Objetivos de Aprendizagem

Ao concluir este exercício você será capaz de:

  • Declarar e usar corretamente int argc, char* argv[] na assinatura do main;
  • Iterar sobre argv para identificar flags (--flag) e seus parâmetros numéricos;
  • Validar entradas numéricas e emitir mensagens de erro claras;
  • Combinar múltiplas flags booleanas independentes para compor o comportamento do programa — habilidade diretamente transferível ao projeto passgen.

2. Descrição

O programa dice simula o lançamento de dados poliédricos. O usuário controla o tipo de dado, o número de lançamentos e o formato da saída exclusivamente por argumentos de linha de comando — sem nenhuma leitura interativa (std::cin).

A saída padrão do programa é uma listagem ordenada de todos os lançamentos feitos.

É possível alterar os valores padrão de execução, bem como as informações que o programa exibe por meio da utilização e configuração de flags, conforme detalhado na próxima seção.

3. Especificação da Command Line Interface

O programa dice pode receber os seguintes argumentos.

Flag Parâmetro Descrição Padrão
--sides N inteiro > 0 Número de faces do dado 6
--rolls N inteiro > 0 Quantidade de lançamentos 1
--sum Exibe a soma total dos lançamentos off
--stats Exibe mínimo, máximo e média off
--verbose Mostra cada resultado individualmente off
--help ou -h Exibe as instruções de uso do programa off

Note

O programa dice deve aceitar as flags acima especificadas em qualquer ordem.

4. Exemplos de Uso e Saída Esperada

4.1 Uso mínimo — um lançamento, dado padrão (6 faces)

$ ./dice
Resultado(s): 4

4.2 Solicitação de ajuda

$ ./dice -h
-- Welcome to dice simulation --
This program simulates a dice row
Usage: dice [<options>]
 --sides n The number (>0) of dice faces (default is 6, max is 65535)
 --rolls n Defines how many times (>0) the dice is rolled (default is 1, max is 65535)
 --sum Prints the sum of all rolled faces
 --stats Prints min, max and median of the values rolled
 --verbose Prints extra information
 -h, --help Show this help screen.

4.3 Especificando dado e número de lançamentos

$ ./dice --sides 8 --rolls 15
Resultado(s): 1 2 3 4 4 4 5 5 6 6 6 6 7 8 8

4.4 Flag --verbose

$ ./dice --sides 8 --rolls 10 --verbose
--> 🎲 Lançamento #1: 4
--> 🎲 Lançamento #2: 1
--> 🎲 Lançamento #3: 7
--> 🎲 Lançamento #4: 1
--> 🎲 Lançamento #5: 4
--> 🎲 Lançamento #6: 6
--> 🎲 Lançamento #7: 6
--> 🎲 Lançamento #8: 8
--> 🎲 Lançamento #9: 2
--> 🎲 Lançamento #10: 7
--------------------
Resultado(s): 1 1 2 4 4 6 6 7 7 8

4.5 Flag --sum

$ ./dice --sides 6 --rolls 4 --sum
Resultado(s): 1 3 5 6
Soma: 15

4.6 Flag --stats

$ ./dice --sides 6 --rolls 5 --stats
Resultado(s): 1 2 3 5 6
Mínimo: 1 | Máximo: 6 | Média: 3.40

4.7 Combinando múltiplas flags

$ ./dice --sides 8 --rolls 4 --verbose --sum --stats
--> 🎲 Lançamento #1: 2
--> 🎲 Lançamento #2: 1
--> 🎲 Lançamento #3: 7
--> 🎲 Lançamento #4: 3
--------------------
Resultado(s): 1 2 3 7
Soma: 13
Mínimo: 1 | Máximo: 7 | Média: 3

4.8 Casos de erro — validação obrigatória

Fornecer um valor fora da faixa do unsigned short, ou um valor zero.

$ ./dice --sides 0
>>> Error: Invalid or absent integer value argument provided for the --sides flag.
$ ./dice --sides 65900
>>> Error: Invalid or absent integer value argument provided for the --sides flag.

Esquecer de fornecer o valor numérico para os argumentos que requerem um valor.

$ ./dice --rolls
>>> Error: Missing number of rolls.
$ ./dice --sides
>>> Error: Missing number of faces.

Fornecer um argumento inválido.

$ ./dice --foo
>>> Error: Unrecognised argument "--foo"!

5. Requisitos de Implementação

Obrigatório:

  • O programa deve usar exclusivamente argc e argv — sem getopt, argparse ou bibliotecas externas;
  • A geração de números aleatórios deve usar std::mt19937 semeado com std::random_device;
  • Erros devem ser impressos em stderr e o programa deve retornar código de saída 1;
  • O código deve compilar sem warnings com g++ -std=c++17 -Wall -Wextra -pedantic.

Opcional (bônus):

Implemente os seguintes flags extras:

Flag Parâmetro Descrição Padrão
--seed N inteiro > 0 Define a semente do gerador, tornando os resultados reprodutíveis randômico
--histogram Exibe um histograma ASCII dos resultados off

6. Geração de números aleatórios

Aqui um programa exemplo, random_demo.cpp, adaptado desta referência.

#include <iostream>#include <random>
constexpr short n_times{10}; // How many times to run the dice?

int main() {
 std::random_device rd; // a seed source for the random number engine
#if FIXED_SEED
 // NOTE:
 // Fixed seed means the random generation process always produces the same
 // sequence of number
 std::mt19937 gen(3);
#else
 // NOTE:
 // Random seed created wit rd()
 std::mt19937 gen(rd());
#endif // FIXED_SEED
 std::uniform_int_distribution<> distrib(1, 6);
 // Use distrib to transform/map the random unsigned int
 // generated by gen into an int in [1, 6]
 for (auto n{0}; n < n_times; ++n)
 std::cout << distrib(gen) << ' ';
 std::cout << '\n';
}

É possível compilar o programa random_demo.cpp de duas formas, descritas a seguir.

A versão abaixo, com o -DFIXED_SEED, faz com que a execução do programa produza sempre a mesma sequência, já que a semente de geração está fixa.

Esse controle é muito útil quando se deseja depurar programas, de alguma forma, utilizam valores aleatórios gerados pelo programa. Com o uso da semente fixa, é possível replicar facilmente o resultado de uma execução com geração aleatória.

$ g++ -Wall -std=c++17 random_demo.cpp -DFIXED_SEED

Já a versão abaixo, gera números diferentes a cada execução, visto que a semente passa a ser gerada randomicamente por rd().

$ g++ -Wall -std=c++17 random_demo.cpp

Para se aprofundar na forma como o C++ trabalha com geração de números aleatório, recomendo a leitura dessa página. Outra boa referência, mais didática, é este capítulo do learncpp.com.


The end