Dúvidas EP3 - Perguntar aqui

Dúvidas EP3 - Perguntar aqui

por Carlos Eduardo Bayer -
Número de respostas: 26
Bom dia,
Meu ep está praticamente pronto, mas há um problema:

Nome p1 p2 p3 mp ep1 ep2 ep3 ep4 ep5 mep mf
Cassandra Avestruz da Silva 5.0 6.6 4.2 5.3 10.0 9.0 8.0 7.0 6.0 7.4 6.7

0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Nicolau dos Santos Neto 3.2 2.0 1.5 2.0 4.2 3.1 2.4 1.5 0.0 1.7 1.8

0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Romario de Souza Faria 8.0 3.0 7.7 5.9 9.5 8.0 10.0 9.5 9.0 9.3 8.1
Medias 5.4 3.9 4.5 4.4 7.9 6.7 6.8 6.0 5.0 6.1 5.6

Aprovados: 2
Recuperacao: 0
Reprovados: 3

Ele imprime esse monte de "0.0" e conta como se fosse um aluno reprovado!! O restante do programa funciona perfeitamente.

Outra questão, o arquivo de entrada que eu uso tem esse endereço C:\Dev-Cpp\entrada.txt e cada vez que eu uso o programa tenho que digitar tudo isso... não há outra maneira mais pratica para o usuário?

Obrigado,
Em resposta à Carlos Eduardo Bayer

Re: Dúvidas EP3 - Perguntar aqui

por Carlos Eduardo Bayer -

Sim, eu estou respondendo minha própria pergunta....
Depois de muitos problemas e muitas idéias frustradas eu coloquei duas vezes o "fgets(nome, MAX_NOME, entrada);" e funcionou.

Fica aí a dica para quem quiser.

Mas ainda aguardo a resposta sobre o endereço do arquivo.

Abraços,

Em resposta à Carlos Eduardo Bayer

Re: Dúvidas EP3 - Perguntar aqui

por Francisco Reverbel -
Provavelmente a leitura do campo numérico imediatamente anterior ao nome foi feita com "%d" ou "%f", que não consomem o '\n' ao final da linha anterior à do nome. Aí o fgets pega esse '\n' e considera como uma linha vazia. Colocando dois fgets você contorna o problema, pois o primeiro pega a "linha vazia" (o '\n' que sobrou da leitura do campo numérico anterior) e o segundo pega o nome. Entretanto, essa "solução" (dois fgets) não é uma boa solução! Ela é um "trambique"... A maneira correta de resolver o problema é remover o segundo fgets e ler os campos numéricos com "%d " e "%f " (note o espaço depois do %d e do %f), como o enunciado sugere.

Na verdade, os campo numéricos que realmente precisam do espaço no "%d " ou "%f " são aqueles que vem logo antes de um campo de texto (o nome), pois o fgets e o "%c" não pulam espaços em branco (espaços, new lines e tabs) antes da leitura. Mas não faz mal nenhum usar o espaço na leitura de qualquer campo numérico.
Em resposta à Carlos Eduardo Bayer

Re: Dúvidas EP3 - Perguntar aqui

por Bruno Del Papa -

Oi,

Existe um numero máximo de provas e eps que o programa deve aceitar? Ou ele deve funcionar para qualquer quantidade de provas e eps?

Obrigado

Em resposta à Bruno Del Papa

Re: Dúvidas EP3 - Perguntar aqui

por Francisco Reverbel -
O enunciado foi omisso neste ponto, mas é muito razoável que hajam limites para o número de provas e para o número de EPs que o programa aceita. Com o que vimos em classe, não dá para fazer o EP sem tais limites...

Escolha limites bem folgados: 40 provas e 40 EPs, por exemplo. Para que seja fácil alterar esses limites, defina-os como constantes simbólicas:

#define MAX_PROVAS 40
#define MAX_EPS    40
Em resposta à Carlos Eduardo Bayer

Re: Dúvidas EP3 - Perguntar aqui

por Rebeca Bayeh -

Sobre o EP3...

Podemos tirar o "exit(1)" na abertura do arquivo de entrada e, no lugar disto, perguntar novamente o nome do arquivo de entrada até que o usuário digite corretamente?

e o que mais deve aparecer na tela do programa? ou basta criar o arquivo de saída, sem mais formalidades?

Em resposta à Rebeca Bayeh

Re: Dúvidas EP3 - Perguntar aqui

por Rodrigo Cordeiro Godoy -
Você poderia colocar realmente este loop até que fosse entrado o nome correto, mas isto impediria também o programa de sair caso não tenha nenhum arquivo de entrada, Rebeca.

E o enunciado realmente não especifica nada sobre o que é mostrado na tela, o importante é o arquivo de saída.
Em resposta à Rodrigo Cordeiro Godoy

Re: Dúvidas EP3 - Perguntar aqui

por Nancy Falcao -

Tenho uma duvida..

Qdo a media da tipo.. 4.96.. na hora de imprimir fica 5.0 mas para avaliar se o aluno esta ou nao em recuperaçao (ou aprovado) ele vai considerar como se fosse menor que 5.. entao o aluno nao foi aprovado por mais q no arquivo de saida a media dele seja 5.0

Como devemos proceder nesse caso?

Em resposta à Nancy Falcao

Re: Dúvidas EP3 - Perguntar aqui

por Francisco Reverbel -
Duas possibilidades, ambas aceitáveis para efeito do EP3:

1) Você pode considerar que uma média do tipo 4.96 é um "caso patológico" e simplesmente ignorar o problema, deixando que o aluno fique reprovado mesmo que a média dele (arredondada) seja 5.0.

2) Você pode fazer o que muitos professores fazem em suas planilhas: considere que o limiar para aprovação é 4.95. Em outras palavras, quando estiver decidindo quem vai ser aprovado e quem vai ser reprovado, compare cada média com 4.95 (em vez de comparar com 5.0). piscando
Em resposta à Carlos Eduardo Bayer

Re: Dúvidas EP3 - Perguntar aqui

por Bruna Alves -
Gostaria de fazer upload do meu ep3, mas ainda não existe o link para isso. Viajo amanha de noite e nao terei acesso a internet até segunda de manhã! Até amanhã estará disponivel a area para a entrega do ep3?

obrigada


Em resposta à Carlos Eduardo Bayer

Re: Dúvidas EP3 - Perguntar aqui

por Gustavo Soares -
Eu usei o comando #define MAX_NOME 30 e na hora de usar o fgets, fiz conforme o escrito no enunciado: fgets(nome, MAX_NOME, entrada);

Entretanto, na hora de imprimir no arquivo de saída, fiz um teste e notei que ele imprime tudo, além do limite MAX_NOME.

Assim, para o seguinte comando:

fgets(nome, MAX_NOME, entrada);
fprintf(saida, "%s", nome);

aparece:

Cassandra Avestruz da Silva 5.0 6.6 4.2 10.0 9.0 8.0 7.0 6.0

sendo que o vetor nome[MAX_NOME] está limitado pelo #define MAX_NOME 30. Ou seja, seria como se o fgets "desrespeitasse" o MAX_NOME e só parasse de ler ao chegar no fim da linha. Alguém sabe por que motivo isso ocorre?
Em resposta à Gustavo Soares

Re: Dúvidas EP3 - Perguntar aqui

por Gustavo Soares -
fiz outro teste, e deu mais ou menos certo. O problema está no laço que criei. Ao tirar o

fgets(nome, MAX_NOME, entrada);
fprintf (saida, "%s", nome);

do laço, foi lido apenas o nome com os brancos restantes para completar o vetor até chegar no MAX_NOME.

Vocês não precisam responder à dúvida anterior sorriso
Em resposta à Gustavo Soares

Re: Dúvidas EP3 - Perguntar aqui

por Nancy Falcao -

duvida.. quais arquivos se fecha no final de programa?

o de entrada? o de saida? os 2?

Em resposta à Gustavo Soares

Re: Dúvidas EP3 - Perguntar aqui

por Rodrigo Cordeiro Godoy -
Gustavo, quando você cria um vetor com 30 chars, ele vai da posição 0 até a 29, e se você mandar ele preencher ele com um nome de 30 letras o nome irá ocupar todo o espaço do vetor, isto nunca é desejado.

Quando você manda por exemplo o printf imprimir um "%s", ele vai imprimir o vetor todo até encontrar um "\0" (barra-zero) no final. O "\0" é colocado no final do vetor pelo fgets, mas isso não acontece caso o nome tenha 30 letras, porque então o vetor todo seria preenchido.

Então normalmente o que se faz é declarar o vetor com um espaço a mais por precaução (31, no caso), assim existirá a posição vetor[30] e ela será ocupada por um "\0" caso o nome tenha 30 letras.

Espero ter ajudado.
Em resposta à Rodrigo Cordeiro Godoy

Re: Dúvidas EP3 - Perguntar aqui

por Gustavo Soares -
Godoy, lembro que na quarta-feira durante sua monitoria na pró-aluno, vc ajudou a Roberta sugerindo um while no programa dela, que imprimia vários 0.0. O que era esse while?

Além disso, estou com um problema relacionado às notas. Como vc pode ver mais abaixo, o vetor que deveria ler as notas de provas e colocá-las no arquivo de saída lê e imprime a última nota da linha anterior. Além disso, o vetor de notas dos EPs não lê nem imprime as notas do 4º e do 5º EP. Os vetores e variáveis relacionados às médias funcionam sem problema, mas os que citei anteriormente estão com esse defeito. Acredito que isso esteja relacionado à leitura das notas no arquivo de entrada. Existe algum comando que possa solucionar isso?

Segue abaixo a impressão na saída:


Nome p1 p2 p3 mp ep1 ep2 ep3 ep4 ep5 mep mf
Cassandra Avestruz da Silva 0.0 0.0 0.0 5.3 10.0 9.0 8.0 7.4 6.7
Nicolau dos Santos Neto 6.7 6.7 6.7 2.0 4.2 3.1 2.4 1.7 1.8
Romário de Souza Faria 1.8 1.8 1.8 5.9 9.5 8.0 10.0 9.3 8.1
Medias 5.4 3.9 4.5 4.4 7.9 6.7 6.8 6.0 5.0 6.1 5.6

Aprovados: 2
Recuperação: 0
Reprovados: 1

Em resposta à Gustavo Soares

Re: Dúvidas EP3 - Perguntar aqui

por Gustavo Soares -
Voltei à idéia inicial de um vetor para todas as notas (ao invés de um para provas e outro para EPs) e consegui resolver o problema. Agora o programa funciona perfeitamente. Não precisam responder à minha pergunta sorriso
Em resposta à Gustavo Soares

Re: Dúvidas EP3 - Perguntar aqui

por Rodrigo Cordeiro Godoy -
"Godoy, lembro que na quarta-feira durante sua monitoria na pró-aluno, vc ajudou a Roberta sugerindo um while no programa dela, que imprimia vários 0.0. O que era esse while?"

Eu sei que você já resolveu o problema mas, respondendo isto que você disse, eu não falei pra ela fazer este while sugerido não.

O problema que a roberta estava tendo é que o programa dela estava lendo o "\n" no final das notas de cada linha como se fosse um nome, então eu sugeri para ela colocar a linha que pegava o nome do aluno em um do...while, caso o primeiro caractere do nome fosse um "\n" algo estava errado.

O problema também poderia ser corrigido usando um fgetc simples no final de cada iteração.

Não falei nada sobre imprimir 0.0, não.
Em resposta à Rodrigo Cordeiro Godoy

Re: Dúvidas EP3 - Perguntar aqui

por Gustavo Soares -
ah sim, então eu acabei confundindo as coisas. Eu lembrava que tinha algo a ver com a leitura de algo, e achei que poderia ajudar a consertar o problema que tinha no meu programa.
Em resposta à Carlos Eduardo Bayer

Re: Dúvidas EP3 - Perguntar aqui

por ARTUR SCAVONE -
Rodrigo, eu vi minha nota no EP3 e voce citou um warning por causa de um int antes do fclose. Eu uso do dev c++ com windows xp. No meu ambiente não recebo nenhum warning. E estou com o mesmo código que enviei a voce. Há uma explicação pra isso?

Artur
Em resposta à Carlos Eduardo Bayer

Re: Dúvidas EP3 - Perguntar aqui

por ARTUR SCAVONE -

Rodrigo,

Ainda sobre o EP3. Eu tenho um pedido de esclarecimento agora com mais detalhes. Eu perdi ponto no EP3 porque usei:

int fclose(FILE *entrada);

Mas essa forma eu COPIEI do help do DEV C++ conforme o exemplo que eles fornecem abaixo:

______________________________________________________________

FILE *fp;

if ((fp = fopen("myfile", "r")) ==NULL){
  printf("Error opening file\n");
  exit(1);
}

To close a file, use fclose(), whose prototype is

int fclose(FILE *fp);

______________________________________________________________

Se voce entrar no help do DEV C++ (para windows xp) e pedir FILE HANDLING este exemplo está lá. Como eu não obtive nenhum WARNING, deixei assim.

Eu queria entender onde está o erro. E queria ver minha nota reconsiderada  sorriso

Grato,

Artur

 

Em resposta à ARTUR SCAVONE

Re: Dúvidas EP3 - Perguntar aqui

por Rodrigo Cordeiro Godoy -
Olá Artur,

No help do Dev (tanto quanto no man do linux) ele diz o protótipo da função. Realmente está escrito "int fclose()" mas isto no protótipo só quer dizer que a função devolve um inteiro (que é usado para mais informações sobre o fechamento do arquivo).

O scanf, por exemplo, também tem o mesmo protótipo (e algumas pessoas usaram isso no EP). Mas não é para ser usado como você usou, a informação por exemplo poderia ter sido guardada em uma variável. O scanf devolve o número de itens que combinaram com o que você colocou entre aspas.

A função fclose devolve 0 se conseguiu fechar o arquivo corretamente, então você poderia ter feito algo como:

int aux;
(...)

aux = fclose(arquivo);

if (aux == 0) {
printf("Erro ao fechar o arquivo!\n");
exit(1);
}

Entendeu?

Sobre o warning não aparecer no Dev, eu não tenho idéia de por que ele não apareceu, talvez o Dev tenha interpretado como um cast de int para o resultado.
Em resposta à Rodrigo Cordeiro Godoy

Re: Dúvidas EP3 - Perguntar aqui

por Nancy Falcao -

Falando nisso.. eu ja havia falado com o professor.. mas o dev tb nao acusou alguns warnings q ele deveria ter avisado.. tanto o do caso do meu ep1 (declaraçao de variavel.. um printf e outra declaraçao) como nao ta acusando qdo uma variavel ta inutil no programa (q deveria tb dar um warning e nao esta dando) e meu dev ta com td q vcs falaram pra por..

Outra coisa.. aquele \n no final do arquivo de saida era necessario? pq nao vi onde tava escrito q ele deveria existir e nao interferiu no resultado final (q ficou identico ao mostrado no enunciado do ep)

Alias, nesse ep.. na saida da foto lah.. tb tem q ter algum \n? pq nao tem nada falando no enunciado e sem \n algum tb nao ta interferindo.. mas depois do ep anterior.. vah saber... bom perguntar antes

Em resposta à Nancy Falcao

Re: Dúvidas EP3 - Perguntar aqui

por Rodrigo Cordeiro Godoy -
Os finais dos arquivos (de texto principalmente) são sempre marcados com um \n. No caso do windows especialmente. É uma diferença sutil que pode levar a alguns programas que lêem estes arquivos ao travamento.

Colocar um \n no final de um arquivo não modifica em nada ele tirando este detalhe. Pode colocar um \n no final das imagens .pgm também (depois do último número (pixel)).
Em resposta à ARTUR SCAVONE

Re: Dúvidas EP3 - Perguntar aqui

por Francisco Reverbel -
Olá Artur,

Com o gcc o warning que aparece é este:

$ gcc -ansi -pedantic -O2 -Wall -o ep3-6567511 ep3-6567511.c
ep3-6567511.c: In function ‘main’:
ep3-6567511.c:144: warning: ISO C90 forbids mixed declarations and code

Esse warning indica que pela linha 144 do seu programa há declarações misturadas com código executável. De fato, as linhas 144 e 145 são

int fclose(FILE *entrada);
int fclose(FILE *saida);

Embora sua intenção fosse fazer duas chamadas à função fclose, essas linhas não são chamadas de função! Elas são declarações (protótipos) da função fclose. Como em C as declarações têm que aparecer antes do código executável, o compilador gerou o warning. Para chamar fclose, essas linhas deveriam ser assim:

fclose(entrada);
fclose(saida);

Seria ainda melhor (porém não obrigatório) verificar o valor devolvido por fclose, como o Rodrigo explicou:

if (fclose(entrada) != 0)
    printf("Erro no fechamento do arquivo de entrada\n");

if (fclose(saida) != 0)
    printf("Erro no fechamendo do arquivo de saida\n");

Eu também não sei porque o DevC++ não deu warning. Não estou com o DevC++ agora, senão faria um teste.

Reverbel