Enrere Mòdul 8
Fonaments de Programació. Llenguatge C/C++---
Pràctica    Resum teòric Exercicis
Pràctica d'ampliació

 
Modificació de les dades d'un arxiu.

En aquesta pràctica modificarem les dades de la pràctica d'ampliació 1 d'aquest mòdul.

 

Desenvolupament de la pràctica

Creeu un nou arxiu del tipus C++ anomenat m8p2.cc i escriviu el següent codi:

//m8pa2.cc - llegir i escriure resgistre
#include <stdio.h>

// prototipus de les funcions
void lectura_tot_arxiu();

typedef struct {
   char nom[20];
   int edat;
} persona;

FILE *f1;
persona dada;

int main()
{
   int nombreRegistres;


   // Obriem l'arxiu per lectura i escriptura
   f1 = fopen ("alumnes.dat", "rb+");
   if (f1 == NULL)
   {
       perror("No es pot obrir alumnes.dat");
       return -1;
   }

   //Obtenim el total de resgistres que hi ha en el fitxer
   fseek(f1, 0, SEEK_END);
   nombreRegistres = ftell(f1)/sizeof(dada);
   printf ("\n Dins el fitxer hi ha %d resgistres  \n",nombreRegistres);

   // Portem el cursor al cinquè registre, index 4
   fseek (f1, 4*sizeof(dada), SEEK_SET);

   // Mostrem la informació
   fread (&dada, sizeof(dada), 1, f1);
   printf ("nom = %s\n", dada.nom);
   printf ("edat = %d\n", dada.edat);


   //Modifiquem les dades de l'estructura
   printf("\n Introduïu un nou nom ");
   scanf("%s",dada.nom);
   printf("\n Introduïu la nova edat ");
   scanf("%d",&dada.edat);

   // Ens situem a l'inici del registre 5
   fseek(f1, 4*sizeof(dada), SEEK_SET);

   // escribim damunt
   fwrite (&dada, sizeof(dada), 1, f1);
   fclose(f1);

   //lectura de tot l'arxiu per comprovar els canvis
   lectura_tot_arxiu();

    return 0;
}

void lectura_tot_arxiu()
{
   f1 = fopen ("alumnes.dat", "rb+");
   if (f1 == NULL)
   {
      perror("No es pot obrir alumnes.dat");
      return;
   }


   while(fread (&dada, sizeof(dada), 1, f1))
       printf("\n nom %s edat %d",dada.nom, dada.edat);

}

 

Captura de l'execució del programa.

 

Explicació del programa

La funció fseek() ens permet desplaçarnos ràpidament sense la necessitat d'anar llegint sequncialment el fitxer fins una posicio determinada. Aixó és el que es coneix com acces aleatori.

Obtenim el total de registres que hi ha en el fitxer amb el següent codi:

   fseek(f1, 0, SEEK_END);
   nombreRegistres = ftell(f1)/sizeof(dada);

Utilitzem fseek() que ens ermet moure el cursor a una posició determinada del fitxer. En aquest cas el portem al final del fitxer ( SEEK_END ). ftell () retorna la posició, en bytes, del punter respecte a l'inici. El retorn d'aquest funció el dividim per la grandària de cada registre i  tenim el nombre de registres que tenim dins el fitxer.

Volem modificar el cinquè registre. EL primer que hem de fer és calcular en quin byte comença aquest registre. Això és fàcil. Cada registre té una grandària en bytes de  sizeof(dada) . El primer comença en un desplaçament de 0 bytes, el segon sizeof(dada), el  tercer en 2*sizeof(dada), i així successivament.

El nostre registre és 4*sizeof(dada),  ja que es  comença a contar per zero.

   fseek (f1, 4*sizeof(dada), SEEK_SET);
 

Llegim i  mostrem la informació

   fread (&dada, sizeof(dada), 1, f1);
   printf ("nom = %s\n", dada.nom);
   printf ("edat = %d\n", dada.edat);

Modifiquem les dades de l'estructura


   //Modifiquem les dades de l'estructura
   printf("\n Introduïr un nou nom ");
   scanf("%s",dada.nom);
   printf("\n Introduïr la nova edat ");
   scanf("%d",&dada.edat);

Ens desplaçament amb SEEK_SET des de el començament del fitxer a la  posició 4*sizeof(dada) i sobreescribim.

   fseek(f1, 4*sizeof(dada), SEEK_SET);

   fwrite (&dada, sizeof(dada), 1, f1);
   fclose(f1);
 

 Per últim llegim tot el fitxer per comprovar que la modificació s'ha realitzat.

 
 

void lectura_tot_arxiu()
{
   f1 = fopen ("alumnes.dat", "rb+");
   if (f1 == NULL)
   {
      perror("No es pot obrir alumnes.dat");
      return;
   }


   while(fread (&dada, sizeof(dada), 1, f1))
       printf("\n nom %s edat %d",dada.nom, dada.edat);

}