psantos10 Posted July 5, 2012 at 11:39 AM Report Share #467398 Posted July 5, 2012 at 11:39 AM Prezados, Preciso da vossa ajuda. Tenho este programa feito em C (estou a estudar atraves d livro de C do Luis Damas 19ª Edição): /* Programa Pauta.c Este programa manipula dados guardados no ficheiro pauta.dat que se encontra no directorio corrente. Se este ficheiro não existir, ele é criado automáticamente. Nota: Os registos são numerados a partir do 0. Ou seja, o primeiro registo é 0, o segundo é 1 e assim por diante... */ #include<stdio.h> #include<stdlib.h> #include <string.h> FILE *ficheiro; char *nome_ficheiro = "pauta.dat"; struct aluno { char nome[20]; float nota_freq; float nota_exame; float media_final; }; int Escolhe() { int opcao; do { system("cls"); printf("\n\t\tUNIVERSIDADE CATOLICA DE ANGOLA\n\t\t\t== PAUTA FINAL ==\n\n"); printf("Nome: Patricio dos Santos\nN: 11095\n\n"); // Menu Principal... printf("\t\t1 - Inserir Novo Aluno\n"); printf("\t\t2 - Alterar um Aluno\n"); printf("\t\t3 - Pesquisar um Aluno\n"); printf("\t\t4 - Mostrar Pauta\n"); printf("\t\t5 - Eliminar Aluno\n"); printf("\t\t0 - SAIR\n\n"); printf("\nESCOLHE UMA OPCAO: "); scanf("%d", &opcao); } while (opcao < 0 || opcao > 6); return opcao; } void NovoRegisto() { char lixo[255]; struct aluno um_aluno; // Limpa o buffer do teclado gets(lixo); // Posiciona o cursor do final do arquivo fseek(ficheiro,0,SEEK_END); printf("\nDigite os dados do Novo Aluno:\n"); printf("Nome do Aluno: "); gets(um_aluno.nome); printf("Nota da P. Freq.: "); scanf("%f", &um_aluno.nota_freq); //gets(um_aluno.nota_freq); printf("Nota de Exame: "); scanf("%f", &um_aluno.nota_exame); um_aluno.media_final = (um_aluno.nota_exame + um_aluno.nota_freq) / 2.0; // Gravar o novo registo fwrite(&um_aluno, sizeof(struct aluno), 1, ficheiro); printf("\nRESULTADO: Aluno gravado com sucesso!\n\n"); system("PAUSE"); } // Função para mostrar todos os alunos... void MostrarPauta() { int reg; struct aluno um_aluno; // Posicioa o Cursor no inicio do Ficheiro fseek(ficheiro,0,SEEK_SET); reg = 0; printf("\n\n-----------------------------------------------------------\nNOME\tNOTA DE FREQ.\tNOTA DE EXAME\tMEDIA\n-----------------------------------------------------------\n"); do { // Lê o registo... fread(&um_aluno, sizeof(struct aluno), 1, ficheiro); // Parar quando chegar ao fim do ficheiro... if (feof(ficheiro)) break; // Mostrar pauta printf("%s\t%.2f\t\t%.2f\t\t%.2f\n", um_aluno.nome, um_aluno.nota_freq, um_aluno.nota_exame, um_aluno.media_final); reg++; } while (!feof(ficheiro)); // Repete enquanto não chegar ao fim do ficheiro... printf("\n-----------------------------------------------------------\n"); printf("\n\n"); system("PAUSE"); } // Função para pesquisar um aluno void PesquisarAluno() { int reg; struct aluno um_aluno; printf("Informe o Numero do Aluno: "); scanf("%d", ®); // Posicione o cursor no registo desejado... fseek(ficheiro,reg*sizeof(struct aluno),SEEK_SET); // Lendo o registo... fread(&um_aluno, sizeof(struct aluno), 1, ficheiro); // Verificiar se o Registo Existe... if (feof(ficheiro)) { printf("\rALUNO NÃO ENCONTRADO!\n"); return; } // Mostrar pauta printf("\n\n-----------------------------------------------------------\nNOME\tNOTA DE FREQ.\tNOTA DE EXAME\tMEDIA\n-----------------------------------------------------------\n"); printf("%s\t%.2f\t\t%.2f\t\t%.2f\n", um_aluno.nome, um_aluno.nota_freq, um_aluno.nota_exame, um_aluno.media_final); printf("\n-----------------------------------------------------------\n"); printf("\n\n"); system("PAUSE"); } // Eliminar Aluno... void EliminarAluno() { int reg; struct aluno um_aluno; struct aluno zero; printf("Informe o Numero do Aluno: "); scanf("%d", ®); fflush(stdin); // Posicione o cursor no registo desejado... fseek(ficheiro,reg*sizeof(struct aluno),SEEK_SET); //fwrite(&zero,sizeof(struct aluno),1,ficheiro); // Lendo o registo... //fread(&um_aluno, sizeof(struct aluno), 1, ficheiro); // Verificiar se o Registo Existe... if (feof(ficheiro)) { printf("\rALUNO NÃO ENCONTRADO!\n"); return; } //fseek(ficheiro,reg*sizeof(struct aluno),SEEK_SET); if (fwrite(&zero,sizeof(struct aluno),1,ficheiro) != 1) { printf("\nNão foi possivel eliminar..."); } else { printf("Eliminado com sucesso..."); } // Mostrar pauta //printf("\n\n-----------------------------------------------------------\nNOME\tNOTA DE FREQ.\tNOTA DE EXAME\tMEDIA\n-----------------------------------------------------------\n"); //printf("%s\t%.2f\t\t%.2f\t\t%.2f\n", um_aluno.nome, um_aluno.nota_freq, um_aluno.nota_exame, um_aluno.media_final); //printf("\n-----------------------------------------------------------\n"); printf("\n\n"); system("PAUSE"); } // Alterar Aluno... void AlterarAluno() { int reg; struct aluno um_aluno; printf("Informe o Numero do Aluno: "); scanf("%d", ®); // Posicione o cursor no registo desejado... fseek(ficheiro,reg*sizeof(struct aluno),SEEK_SET); // Lendo o registo... fread(&um_aluno, sizeof(struct aluno), 1, ficheiro); // Verificiar se o Registo Existe... if (feof(ficheiro)) { printf("\rALUNO NÃO ENCONTRADO!\n"); return; } printf("\nDigite o Novo nome: "); scanf("%s", &um_aluno.nome); printf("\nDigite a Nova nota da Prova de Freq.: "); scanf("%f", &um_aluno.nota_freq); printf("\nDigite a Nova nota de Exame: "); scanf("%f", &um_aluno.nota_exame); um_aluno.media_final = (um_aluno.nota_freq + um_aluno.nota_exame) / 2.0; // Gravando... if (fwrite(&um_aluno, sizeof(um_aluno), 1, ficheiro) != 1) { printf("\nNão foi possivel actualizar..."); } else { printf("Actualizado com sucesso..."); } printf("\n\n"); system("PAUSE"); } // Entrada do Programa.... main() { int opcao; // Abre o Ficheiro ficheiro = fopen(nome_ficheiro, "ab+"); do { opcao = Escolhe(); if (opcao == 1) NovoRegisto(); if (opcao == 2) AlterarAluno(); if (opcao == 3) PesquisarAluno(); if (opcao == 4) MostrarPauta(); if (opcao == 5) EliminarAluno(); } while (opcao != 0); // Saída do Programa... printf("\t\t\tObrigado por utilizar o Programa.\n\n\t\t\tAte Breve...\n\n"); fclose(ficheiro); return(0); } O que acontece é o seguinte: a opção inserir novo, pesquisar e listar funcionam perfeitamente. O problema surge quando teto eliminar ou actualizar. Quando tenta elimina o antigo permanece e é adicionado um nivi registo com caracteres estranhos... e quando tento actualizar nada é feito. Grato pela atenção -------Assinatura? Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted July 5, 2012 at 12:07 PM Report Share #467408 Posted July 5, 2012 at 12:07 PM eu não conheço esse livro, apesar de toda a gente o recomendar. no entanto eu pergunto-me, estás a seguir um exemplo por passos que tem no livro, ou estás a tirar ideias ? porque eu pergunto-te: se o ficheiro tiver mais do que dois registos de alunos, tu pesquisas por um que não seja o último, sabes o que acontece se chamares a função de criar um novo registo de seguida ? IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
psantos10 Posted July 5, 2012 at 01:58 PM Author Report Share #467444 Posted July 5, 2012 at 01:58 PM prezado... estou a ler o livro do Luís Damas para aprender a programar em C... o exemplo acima está a ser criado por mim... utilizando os coceitos que estão no livro.. o exemplo em si não se encontra no livro. Consigo guardar vários registos... como podes ver no código... assim como consigo listar... só a alteração e o remoção é que não funcionam. Grato pela atenção Cumps PS -------Assinatura? Link to comment Share on other sites More sharing options...
pmg Posted July 5, 2012 at 02:04 PM Report Share #467446 Posted July 5, 2012 at 02:04 PM (edited) Primeiro: não uses gets(). Não é possível usar esta função com segurança (evitando "buffer overflows") pois ela não tem mecanismos para controlar o número de bytes guardados. Aumentando um bocadinho que disse o Hippo, o que te está a acontecer é o seguinte: Supoe que o ficheiro tem 3 registos e tu queres alterar o segundo; Eu represento o ficheiro e os 3 registos assim AAAAAAAABBBBBBBBCCCCCCCC Depois de leres o primeiro e o segundo registo, o ponteiro fica a apontar para o terceiro AAAAAAAABBBBBBBBCCCCCCCC ^ Se imediatamente a seguir escreves o segundo registo alterado, o que acontece é isto: AAAAAAAABBBBBBBBbbbbbbbb ^ Edited July 5, 2012 at 02:04 PM by pmg What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código! Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted July 5, 2012 at 02:06 PM Report Share #467447 Posted July 5, 2012 at 02:06 PM no entanto não respondeste à minha pergunta. então vou responder eu imagina que tens no ficheiro o aluno 1 e aluno 2. ao fazeres a pesquisa do aluno 1 deixas o apontador da stream ficheiro prontinha para ler o aluno seguinte fseek(ficheiro,reg*sizeof(struct aluno),SEEK_SET); // Lendo o registo... fread(&um_aluno, sizeof(struct aluno), 1, ficheiro); /* o comentário que falta aqui é que o ponteiro fica na posição : (reg+1)*sizeof(struct aluno) * que no teu ficheiro binário é a posição que guarda a informação do segundo aluno */ no entanto, ao pedires para criar um novo registo : fwrite(&um_aluno, sizeof(struct aluno), 1, ficheiro); /* ok, gravou o novo aluno no ficheiro, mas pergunta fundamental é aonde. * pois é, como vimos ainda agora, o ponteiro interno da stream estava a apontar para o segundo aluno * logo podes dizer adeus à informação deste aluno porque foi sobreposta com a informação do novo aluno */ IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now