// dades que sobreviuen al programa

Fitxers en C

Tot el que havies escrit fins ara es perdia en acabar el programa. Un fitxer permet desar dades al disc — i tornar-les a llegir la pròxima vegada.

Obrir i tancar un fitxer

fopen() i fclose()

FILE *f;

f = fopen("notes.txt", "w");
if (f == NULL) {
    printf("Error obrint el fitxer\n");
    return 1;
}

// ... llegir o escriure ...

fclose(f);

FILE * és un apuntador especial que representa el fitxer obert. El segon argument de fopen és el mode: "r" (lectura; el fitxer ha d'existir), "w" (escriptura; el crea si no existeix, o el buida si ja hi era) i "a" (afegir al final, sense esborrar el que ja hi havia). Si fopen no pot obrir el fitxer, retorna NULL — per això cal comprovar-ho sempre, igual que amb malloc.

No t'oblidis mai de fclose: és el que assegura que tot el que has escrit es desa de debò al disc.

Escriptura i lectura formatada

fprintf i fscanf funcionen exactament com printf i scanf, només que el primer argument és el fitxer, no la pantalla ni el teclat.

fprintf(f, "%s %d\n", "Jordi", 16);   // escriu al fitxer, no al terminal

fscanf(f, "%s %d", nom, &edat);       // llegeix del fitxer, no del teclat

Llegir línia a línia

Per processar un fitxer sencer sense saber per endavant quantes línies té, es llegeix amb fgets dins d'un bucle fins que no en quedin més.

char linia[50];

while (fgets(linia, 50, f) != NULL) {
    printf("%s", linia);
}

fgets ja la coneixies del teclat (stdin); aquí l'únic que canvia és llegir d'un FILE * en lloc de stdin. Quan ja no hi ha més línies per llegir, fgets retorna NULL, i el bucle s'atura tot sol.

Taula de referència

FuncióFa
fopen(nom, mode)obre el fitxer; retorna NULL si falla
fclose(f)el tanca i desa els canvis
fputc(c, f) / fgetc(f)escriu / llegeix un sol caràcter
fputs(s, f) / fgets(s, mida, f)escriu / llegeix una línia
fprintf(f, ...) / fscanf(f, ...)escriptura / lectura formatada
fread(...) / fwrite(...)llegeixen / escriuen blocs de bytes en cru (registres sencers, no text)
ferror(f)cert si hi ha hagut algun error amb aquest fitxer

Mira el fitxer omplir-se i buidar-se pas a pas

Fixa't que fprintf i fscanf no toquen mai el terminal: el panell "Fitxer" és on passa l'acció.

Escriptura i lectura

Línia a línia

Codi

Variables

NomValor

Fitxer

Terminal

Pas 1 / 1

Problemes per resoldre

Sense solució ni comprovació automàtica: escriu el programa, compila'l (gcc programa.c -o programa) i prova'l. Les pistes són plegades perquè les obris només si les necessites.

1. Desar i sumar

Escriu un programa que desi els números 3, 7, 1, 9 i 5 en un fitxer numeros.txt (un per línia). Després, torna'l a obrir, llegeix-los i mostra'n la suma.

Suma: 25
Pistes

Primer un bloc que obre el fitxer en mode "w" i hi escriu els 5 números amb fprintf(f, "%d\n", num);, i fclose.

Després, un altre bloc que l'obre en mode "r" i llegeix amb fscanf(f, "%d", &num) dins d'un bucle, acumulant la suma — fscanf retorna el nombre de valors llegits correctament (1 si n'hi havia, o un valor diferent quan ja no en queden).

2. Comptar línies

Reaprofitant el numeros.txt de l'exercici anterior, escriu un programa que compti quantes línies té.

El fitxer té 5 línies
Pistes

El mateix patró while (fgets(linia, 50, f) != NULL) de la teoria, però en lloc d'imprimir cada línia, incrementa un comptador.

3. Copiar un fitxer

Escriu un programa que copiï el contingut de numeros.txt a un fitxer nou, copia.txt, caràcter a caràcter (amb fgetc i fputc, no amb línies senceres).

Copiat correctament
Pistes

Obre'n dos alhora: un en mode "r" (l'origen) i un altre en mode "w" (el destí).

int c; while ((c = fgetc(origen)) != EOF) { fputc(c, desti); } — fgetc retorna EOF (no NULL, perquè treballa amb un sol caràcter) quan el fitxer s'acaba.

Exercicis d'autoavaluació

Aquests es generen amb valors nous a l'atzar i tenen solució comprovable.

—

Quina serà la sortida per terminal d'aquest programa?