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

 
Escriptura i lectura de registres en disc

En aquesta pràctica aprendrem a llegir i escriure blocs sencers de dades, especialment estructures, amb les funcions fread() i fwrite().

 

Desenvolupament de la pràctica

La llibreria estàndard d'entrades i sortides de C proporciona dues funcions que permeten llegir i escriure blocs sencers de dades. Aquestes funcions són fread() i fwrite() i tenen els següents protocols:

int fread(void *punter, int grandaria_del_element , int nombre_de_elements, FILE *arxiu)

int fwrite(void *punter, int grandaria_del_element , int nombre_de_elements, FILE *arxiu)

Aquestes funcions són especialment interessants per emmagatzemar o recuperar estructures senceres i no camp per camp. 

En aquesta pràctica presentarem dos programes, el primer dels quals permetrà emmagatzemar en un arxiu de disc registres d'una base de dades d'alumnes i notes. L'accés a l'arxiu es farà de registre en registre i no de camp en camp. Els valors dels diferents camps s'introduiran per teclat. Per finalitzar, l'entrada de dades s'haurà d'introduir el valor -1 en el camp codi.

El segon dels programes permetrà llegir registres d'un arxiu i els mostrarà per pantalla. De la mateixa forma que el primer programa, l'accés a l'arxiu es farà de registre en registre.

Creeu un nou arxiu del tipus C anomenat m8p081.c i escriviu el següent codi:

//m8p081.c - Escriptura de registres en disc -

#include <stdio.h>
#include <stdlib.h>


struct fitxa{
     int codi;
     char nom[20];
     char cognom[20];
     float nota;
};

int main(){
 

   FILE *fp;
   struct fitxa alumne;
   char arxiu[12];


   printf("Introduïu el nom de l'arxiu de dades\n");
   scanf("%s",arxiu);

   if((fp=fopen(arxiu, "w"))==NULL){
      printf("Error al intentar obrir l'arxiu\n");
      return;
   }


   while (1){
      printf("\nIntroduïu el codi...");
      scanf(" %d",&alumne.codi); if(alumne.codi==-1) break;

      printf("\nIntroduïu el nom... ");
      scanf(" %s",alumne.nom);

      printf("\nIntroduïu el cognom...");
      scanf(" %s", alumne.cognom);

      printf("\nIntroduïu la nota...");
      scanf(" %f",&alumne.nota);


      fwrite(&alumne,sizeof(alumne),1,fp);
   }

   fclose(fp);
   return 0;
}
 

Explicació del programa

Els registres que emmagatzemarem seran estructures del tipus fitxa definida com a estructura global. Es defineix una variable d'aquesta estructura anomenada alumne. Aquesta variable ens servirà de buffer per escriure tot el registre de cop a l'arxiu.

Per tal de finalitzar l'entrada de dades s'ha posat una comprovació darrere de l'entrada del camp codi. Si el valor introduït és igual a -1, se surt del bucle, es tanca l'arxiu i acaba el programa.

Una vegada introduïts els quatre camps del registre s'emmagatzema de cop a l'arxiu amb la funció fwrite():

 fwrite(&alumne,sizeof(alumne),1,fp);

Aquesta línia es poden llegir com: escriu a l'arxiu apuntat per la variable fp, 1 bloc de 48 octets (sizeof(alumne)=48) començant per l'adreça de memòria apuntada pel punter alumne.

El següent programa mostra com es pot llegir els registres sencers de l'arxiu creat amb el programa anterior.

Creeu un nou arxiu del tipus C anomenat m8p082.c i escriviu el següent codi:

//m8p082.c - Lectura de registres en disc -

#include <stdio.h>
#include <stdlib.h>


struct fitxa{
    int codi;
    char nom[20];
    char cognom[20];
    float nota;
};

int main(){
    FILE *fp;
    struct fitxa alumne;
    char arxiu[12];


    printf("Introduïu el nom de l'arxiu de dades\n");
    scanf("%s",arxiu);

    if((fp=fopen(arxiu, "r"))==NULL){
        printf("Error al intentar obrir l'arxiu\n");
        return;
    }


    while (fread(&alumne,sizeof(alumne),1,fp)){

        printf("%d %20s %20s %f\n",alumne.codi,
                alumne.nom,alumne.cognom, alumne.nota);

     }

     fclose(fp);

     return 0;
}

Explicació del programa

Aquest programa és realment similar a l'anterior. La lectura de dades del disc es fa amb la funció fread() de la següent forma:

    fread(&alumne,sizeof(alumne),1,fp);

Aquest línia pot llegir-se com: llegeix a l'arxiu apuntat per fp 1 bloc de 48 octets i escriu aquests octets a la memòria començant per l'adreça apuntada pel punter alumne.

La funció fread() retorna el nombre d'elements llegits. Aquest pot ser més petit que el tercer argument ( int nombre_de_elements ) en cas d'error o bé si em arribat a final del arxiu.

En el nostre exemple si la funció fread() retorna un valor false ( zero ) ens indicarà que em arribat a final del arxiu de dades.