Mudanças entre as edições de "Projeto final de SOP - turmas 2070114 e 2070115"
Linha 31: | Linha 31: | ||
==23/10: início== | ==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). | + | 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 [http://www.sj.ifsc.edu.br/~msobral/SOP/slides/aula16.pdf|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'': | 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'': | ||
Linha 37: | Linha 37: | ||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
int opcao, lidos; | int opcao, lidos; | ||
+ | |||
+ | do { | ||
+ | // aqui mostra as opções do menu | ||
printf("Digite uma opção: "); | printf("Digite uma opção: "); | ||
lidos = scanf("%d", &opcao); | lidos = scanf("%d", &opcao); | ||
printf("Opção escolhida=%d\n", 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 | ||
+ | |||
</syntaxhighlight> | </syntaxhighlight> | ||
− | 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. | + | 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: |
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
Linha 49: | Linha 57: | ||
do { | do { | ||
− | printf("Digite | + | // 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 | |
− | |||
− | |||
− | |||
− | } while ( | ||
− | |||
</syntaxhighlight> | </syntaxhighlight> |
Edição das 19h30min de 23 de outubro de 2009
Etapa 1
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:
- Criar agenda: criar uma nova agenda, que deve ter um nome único.
- Ler agenda: carregar para a memória uma agenda que reside em um arquivo.
- Gravar agenda: gravar em um arquivo a agenda que reside em mempória.
- Inserir evento: adicionar um novo evento à agenda, que não pode conflitar com o horário de outro evento que já exista.
- Mostrar eventos: mostrar em ordem cronológica todos os eventos da agenda.
- Remover evento: remover um evento específico.
- 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 [1].
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 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 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