Jump to content

Actualizar arquivos binários


psantos10

Recommended Posts

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", &reg);
   // 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", &reg);
   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", &reg);
   // 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

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
Link to comment
Share on other sites

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

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 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

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
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.