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 aprendreu 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 protocols següents:

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 presentem dos programes, el primer dels quals permet emmagatzemar en un arxiu de disc registres d'una base de dades d'alumnes i notes. L'accés a l'arxiu es fa de registre en registre i no de camp en camp. Els valors dels diferents camps s'introdueixen per teclat. Per finalitzar l'entrada de dades, s'ha d'introduir el valor -1 al camp codi.

El segon dels programes permet llegir registres d'un arxiu i els mostra per pantalla. De la mateixa manera que el primer programa, l'accés a l'arxiu es fa de registre en registre.

Definiu un projecte nou anomenat m8p081 i afegiu-hi un arxiu de font C/C++ anomenat m8p081.cpp. Escriviu el codi següent:

//m8p081.cpp: Escriptura de registres en disc

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


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

void 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);
}

Explicació del programa

Els registres que emmagatzemareu són estructures del tipus fitxa definida com a estructura global. Es defineix una variable d'aquesta estructura anomenada alumne. Aquesta variable serveix de buffer (memòria intermèdia) per escriure tot el registre de cop a l'arxiu.

Per 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 s'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 pot 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 programa següent mostra com es poden llegir els registres sencers de l'arxiu creat amb el programa anterior.

Definiu un projecte nou anomenat m8p082 i afegiu-hi un arxiu de font C/C++ anomenat m8p082.cpp. Escriviu el codi següent:

//m8p082.cpp: Lectura de registres en disc

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


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

void 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);
}

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

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

Aquesta 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 heu arribat al final de l'arxiu.

En el vostre exemple, si la funció fread() retorna un valor fals (zero), indica que heu arribat al final de l'arxiu de dades.