Projeto final de SOP - turmas 2070114 e 2070115

De MediaWiki do Campus São José
Revisão de 10h26min de 24 de outubro de 2009 por Msobral (discussão | contribs)
Ir para navegação Ir para pesquisar

Etapa 1

Teste

Outro

Mais um

ultimo

novo

Interface com o usuário da agenda, modelagem de eventos e armazenamento da agenda em memória

Interface

A agenda deve apresentar uma interface de texto. Nessa interface o usuário pode escolher uma das seguintes opções, com as respectivas operações a serem desencadeadas:

  1. Criar agenda: criar uma nova agenda, que deve ter um nome único.
  2. Ler agenda: carregar para a memória uma agenda que reside em um arquivo.
  3. Gravar agenda: gravar em um arquivo a agenda que reside em mempória.
  4. Inserir evento: adicionar um novo evento à agenda, que não pode conflitar com o horário de outro evento que já exista.
  5. Mostrar eventos: mostrar em ordem cronológica todos os eventos da agenda.
  6. Remover evento: remover um evento específico.
  7. Sair: sair do programa.

Eventos

Os eventos devem ser modelados para que contenham as seguintes informações:

  • Título
  • Descrição
  • Data e horário de criação
  • Data e horário de início
  • Data e horário de término
  • Categoria
  • Local
  • Status
  • Recorrência

No programa um evento deve ser guardado em uma variável do tipo struct. Uma struct funciona como um registro, em que diferentes valores logicamente relacionados são agrupados e podem ser manipulados usando uma única variável.

23/10: início

Focou-se a criação da interface, que mostra as opções para o usuário e aguarda que ele digite o número da opção escolhida. Para que a interface repita até que o usuário escolha a opção correspodente a sair do programa, usou-se uma estrutura de repetição while. Para o processamento da opção escolhida discutiu-se que a forma mais conveniente é usar a estrutura de decisão switch ... case (equivalente ao Escolhe ... caso do Portugol). Um resumo sobre isto pode ser visto nas transparências.

Algumas equipes identificaram um problema na leitura da opção pelo teclado. Se o usuário digitar algo que não seja um número inteiro, a interface entra em loop, sempre mostrando o menu de opções. Para exemplificar, veja abaixo a leitura de um número inteiro feita com scanf:

  int main() {
    int opcao, lidos;

    do {
      // aqui mostra as opções do menu

      printf("Digite uma opção: ");
      lidos = scanf("%d", &opcao);
      printf("Opção escolhida=%d\n", opcao);

      // executa a ação correspondente à opção escolhida

    } while (opcao != 7); // neste exemplo, a opção 7 faz a saída do programa
  }

Lembre que o scanf tenta ler o valor digitado de acordo com a especificação contida no formato (no exemplo, "%d" que corresponde a um número inteiro). Se ele conseguir, retorna a quantidade de valores lidos (no exemplo isto é guardado na variável lidos). Assim, se scanf no exemplo acima não conseguir ler o valor digitado, irá retornar 0. O problema é que neste caso o valor que foi digitado fica pendente em memória, quer dizer, o scanf não descarta esse valor, apesar de não ter conseguido lê-lo. Na próxima vez que o scanf for chamado ele vai tentar novamente ler esse mesmo valor, e se der erro o valor vai continuar pendente. Isto só se reverterá quando o scanf especificar um tipo de dado compatível com o valor pendente, ou então se o formato especificar que se deve descartá-lo. Veja assim o exemplo abaixo:

  int main() {
    int x, n;

    do {
      // aqui mostra as opções do menu

      // o laço abaixo faz com que se repita a leitura pelo teclado até que se digite um
      // número inteiro.
      do {
        printf("Digite uma opção: ");
        n = scanf("%d", &x);

        // se n == 0, então scanf não conseguiu ler o valor, porque ele não é do tipo inteiro.
        // Então o valor digitado deve ser descartado. Para descartar tudo o que foi digitado, deve-se
        // chamar de novo o scanf, mas com o formato "%*[^\n]". Isto joga fora toda a linha digitada.
        // Uma explicação sobre formatos do scanf está na sua página de manual (execute "man scanf").
        if (n == 0) {
          n = scanf("%*[^\n]");
        }
      } while (n == 0);

      printf("Opção escolhida=%d\n", opcao);

      // executa a ação correspondente à opção escolhida

    } while (opcao != 7); // neste exemplo, a opção 7 faz a saída do programa
  }

Esse problema da leitura de valores com scanf pode aparecer em outras partes da agenda. Então seria mais prático se o algoritmo contido no programa acima, que repete a leitura do teclado até que se consiga ler uma valor válido, pudesse ser reaproveitado. Isto é um bom exemplo do uso de funções da linguagem C. Uma função é um algoritmo a ser reutilizado. Como todo algoritmo, deve ter dados de entrada, uma sequência de instruções, e fornecer dados de saída como resultado. Veja o exemplo abaixo, que se baseia na leitura do teclado com scanf:

  // Função meu_scanf:
  // Dados de entrada: parâmetro "char * mensagem" é o texto a ser mostrado antes de ler do teclado.
  // Dado de saída: meu_scanf devolve (retorna) um número inteiro que corresponde ao valor lido.

  int meu_scanf(char * mensagem) {
    int x, n;

    do {
      printf(mensagem);
      n = scanf("%d", &x);

      // se n == 0, então scanf não conseguiu ler o valor, porque ele não é do tipo inteiro.
      // Então o valor digitado deve ser descartado. Para descartar tudo o que foi digitado, deve-se
      // chamar de novo o scanf, mas com o formato "%*[^\n]". Isto joga fora toda a linha digitada.
      // Uma explicação sobre formatos do scanf está na sua página de manual (execute "man scanf").
      if (n == 0) {
        n = scanf("%*[^\n]");
      }
    } while (n == 0);

    // aqui meu_scanf retorna o valor lido, que está contido na variável "x"
    return x;
  }

  int main() {
    int opcao;

    do {
      // aqui mostra as opções do menu

      // chama a função "meu_scanf" para ler um número inteiro do teclado.
      opcao = meu_scanf("Digite uma opção: ");

      printf("Opção escolhida=%d\n", opcao);

      // executa a ação correspondente à opção escolhida

    } while (opcao != 7); // neste exemplo, a opção 7 faz a saída do programa
  }

No final destas transparências há um resumo sobre funções. Mais informações estão no curso de linguagem C da UFMG.

28/10 (turma 2070115)