You are on page 1of 5

Assignatura: Informàtica

CURS 2022-23
[Pràctica 8]

PRÀCTICA 8: FITXERS

1 FITXERS EN C++
Incloure prèviament la biblioteca "fstream" on estan definits els tipus de fitxers en C++ i les operacions que es
poden realitzar sobre ells:
#include <fstream>
Hi ha dos tipus de fitxers: d'entrada (només està permès llegir) i d'eixida (només està permès escriure dades). Els dos
tipus d'arxius estan identificats en C++ per dos classes diferents:
ifstream (Input Stream) Arxius d'entrada (lectura).
ofstream (Output Stream) Arxius d'eixida (escriptura).

Declaració de variables:
ifstream entrada; //entrada identifica a un fitxer de lectura.
ofstream eixida; //eixida identifica a un fitxer d'escriptura.

2 Obertura d'un fitxer


Una vegada definida la variable que usarem per a referir-nos al fitxer amb què treballarem, i abans de realitzar cap altra
operació sobre el fitxer, la primera cosa que cal fer és obrir-lo mitjançant l'ordre open:
entrada.open("fentrada.dat ");
Obri el fitxer de text el nom del qual en disc és fentrada.dat i l'associa a la variable entrada. El fitxer que s'obri és un
fitxer de lectura.
eixida.open("fsalida.dat");
Obri el fitxer de text el nom del qual en disc és fsalida.dat i l'associa a la variable eixida. El fitxer que s'obri és un fitxer
d'escriptura.
Si volerem obrir fitxers binaris, hauríem d’afegir el paràmetre ios::binary
entrada.open ("fentrada.dat", ios::binary);
salida.open ("fsalida.dat"m ios:binary);
Tots els arxius d'entrada i eixida que els nostres programes usen tenen dos noms: el vertader nom de l'arxiu (nom físic)
que només s'usa en la cridada a la funció open, que connecta l'arxiu a un flux, i el nom del flux (nom lògic) a què queda
connectat l'arxiu i és el que usarem en les operacions de lectura/escriptura sobre arxius.

3 Afegir dades a un fitxer


Per defecte, els fitxers d'eixida (ofstream) s'obrin només per a escriptura creant el fitxer nou. Si el fitxer ja existia és
esborrat. Per a modificar el mode d'obertura es pot afegir un paràmetre més a la instrucció open, que indica el mode
d'obertura. Només veurem el mode ios::app que serveix per a obrir un fitxer d'eixida en mode afegir, de manera
que no borra el fitxer i la finestra del fitxer es posa després de l'últim element. Si el fitxer no existeix el crea.
nom_fitxer_logic.open (nom_fitxer_fisic, ios::app);
f.open("dades.txt", ios::app);

Si volerem afegir dades a un fitxer binari, posaríem també el paràmetre ios::binary de la següent manera:
nom_fitxer_logic.open (nom_fitxer_fisic, ios::app | ios::binary);

4 Nom d'arxius com a entrades


Per a guardar els noms dels fitxers, així com paraules i frases, existeix en C++ el tipus string.
Per poder utilitzar-lo és necessari incloure la llibreria 'string' (no confondre amb la llibreria 'string.h' o 'cstring')

1
Assignatura: Informàtica
CURS 2022-23
[Pràctica 8]

#include <string>
Les paraules o noms de fitxers (sense espais en blanc) es poden llegir de teclat com els enters o els reals:
string nom;
cout >> nom;
En obrir un fitxer el nom del qual ha estat introduït per l'usuari i emmagatzemat en una variable de tipus string cal
realitzar una conversió usant el mètode c_str()
entrada.open(nom.c_str());

5 Comprovar si un arxiu es va obrir correctament


Una cridada a una funció open pot fallar per diverses raons: si intentem obrir un fitxer d'entrada i no hi ha tal fitxer,
intentem obrir un fitxer d'eixida i no tenim permisos d'escriptura sobre tal fitxer. En estos casos és possible que no es
desplegue un missatge d'error i que el programa continue i faja quelcom inesperat. Per això, és convenient després
d'una cridada a open comprovar si el fitxer no s'ha obert correctament i si és així acabar l'execució del programa:
entrada.open("dades.dat");
if (!entrada)
{
cout << " No es va poder obrir el fitxer d'entrada\n";
}
else
...

6 Operacions sobre arxius: lectura/escriptura en fitxers ‘text’


Llegir informació d'un arxiu (lectura): >>, get, getline.
int x;
char c;
string frase;

/* Funciona amb tipus de dades que permeten la conversió a


* cadena de caràcters.
*/
entrada >> x; // Funciona amb qualsevol tipus de dada
// Si es lligen els caràcters NO es lligen ni
// els espais en blanc ni els bots de línia
// Si es lligen string NOMES es poden llegir
// paraules

entrada.get(c); // Només funciona amb char. Llig TOTS els


// caràcters, inclosos els espais en blanc i
// els salts de línia

getline (entrada, frase); // Només funciona amb string

Escriure informació en un arxiu (escriptura): <<, put


int x;
char c;
/* Funciona amb tipus de dades que permeten la conversió a cadena de
* N caràcters

2
Assignatura: Informàtica
CURS 2022-23
[Pràctica 8]

*/
eixida << x; // Funciona amb qualsevol tipus de dada
eixida.put(c); // Només funciona amb char

En les operacions d'escriptura en arxius podem usar els mateixos modificadors de format que utilitzem en la pràctica 3
per a mostrar informació per pantalla, l'única diferència és que ara les funcions de format les apliquem sobre el fitxer
d'eixida en què volem escriure: eixida.

// Escriurem els números en el fitxer eixida en notació punt fix.


eixida.setf(ios::fixed);
//Escriurem sempre amb un punt els números reals en el fitxer eixida
eixida.setf(ios::showpoint);
//Escriure els números reals amb 2 decimals en el fitxer eixida.
eixida.precisió(2);

Una manera de llegir TOTES les dades d'un fitxer de text separat per espais en blanc és:
...
// L'expresio (lectura) sera false quant siga final de fitxer
while (fich >> dato)
{
// Processar dada
...
}
...
O per llegir TOTS els caràcters d'un fitxer de text (incloent espais en blanc i salts de línia):
...
// L'expresio sera false quant siga final de fitxer
while (fich.get (ch) )
{
// Processar caracter ch
...
}
...

Encara que es pot utilitzar NO ES RECOMANA L'UTILITZACIÓ DEL MÈTODE eof

7 La funció eof()
Esta funció s'utilitza per a detectar el final de fitxer, “end of file” en fitxers de tipus text.
entrada.eof( );
Esta funció ens torna una expressió booleana: true si hem arribat al final del fitxer i ja no hi ha més informació per a
llegir, i false en cas contrari.
En el següent bucle escriurem per pantalla tota la informació del fitxer.
char dada; int dada;
dada = f.get(); //llig abans f >> dada;
while(!f.eof()) while( !f.eof() )
{ {
cout << dada << endl; cout << dada << endl;

3
Assignatura: Informàtica
CURS 2022-23
[Pràctica 8]

dada = f.get(); f >> dada;


} }

NO ES RECOMANA LA UTILITZACIÓ DEL MÈTODE eof

8 Fitxers binaris en C++


L’entrada/eixida en mode binari no fa una conversió a cadena de caràcters, sinó que còpia el contingut d’una zona de
memòria al flux. Els caràcters es bolquen de la mateixa manera en ambdós formats. En la lectura s’actualitza una zona
de memòria directament amb les dades llegits del flux.
Este mètode és més ràpid al no fer la conversió i els fitxers resultants solen ser més xicotets. Per exemple, si s’escriu el
número 3.1415927 en mode text, ocuparà l’espai de 9 caràcters (generalment un caràcter ocupa un byte). Si s’escriu en
mode binari, ocupa l’espai del número en memòria. Esta grandària, donat per sizeof(float), sol ser 4 bytes.
Per a usar estes operacions és convenient que els fluxos s’obriguen en mode binari, indicant en el segon paràmetre de
la funció open si s’obri en mode binari.
ifstream f_bin_ent;
ofstream f_bin_sal;

f_bin_ent.open ("datos_ent.bin", ios::binary);


f_bin_sal.open ("datos sal.bin", ios::binary);

Les operacions de lectura/escriptura en mode binari són:


• read(char *datos, streamsize tam). Esta operació llig del flux a la direcció de memòria apuntada
pel punter dades. Llig tants bytes com indique el paràmetre tam.
• write(const char *datos, streamsize tam). Esta operació escriu en el flux des de la direcció
de memòria apuntada pel punter dades. Escriu tants bytes com indique el paràmetre tam.

La potència d’estes operacions radica en que es pot passar com a primer paràmetre la direcció d’un valor de
qualsevol tipus, per la qual cosa es pot escriure directament un caràcter, un número, o inclús un array o una estructura.
Per a indicar la direcció d’una variable s’usa l’operador &. Cal fer notar que, com per motius d’eficiència, quan en C es
passa un array com a paràmetre, en realitat es passa un punter al primer element. Açò fa que no siga necessari usar &
amb els arrays.
La quantitat de memòria a escriure es calcula automàticament amb l’operació sizeof, que es pot aplicar tant a
variables com a tipus.

Llegir informació d’un arxiu (lectura): read.


entrada.read ((char *)(&x), sizeof(x));
// Funciona amb qualsevol tipus de dada,
// inclosos Vector y Registre (si no
// contenen string)
// NO funciona con el tipus string
// Si volem llegir un string d’un
// fitxer binari ho farem amb >> o
// amb getline

Escriure informació a un arxiu (escriptura): write


salida.write ((char *)(&x), sizeof(x));
// Funciona con qualsevol tipus de dada,
// inclosos Vector i Registre (si no
// contenen string)
// NO funciona amb el tipus string

4
Assignatura: Informàtica
CURS 2022-23
[Pràctica 8]

// Si volem escriure un string en un


// fitxer binari ho farem amb <<

O per a llegir TOTES les dades d’un fitxer binari:


...
// L’expresió serà false quan siga final de fitxer
while (fich.read ( (char *)(&x), sizeof (x) )
{
// Processar informació x
...
}
...

En fitxers binaris NO ES DEURIA utilitzar el mètode eof, ja que és un mètode per a fitxers de tipus text.

9 Tancar fitxers
Tots els arxius han de tancar-se quan el programa haja acabat d'obtindre entrades de l'arxiu o d'enviar eixides a l'arxiu.
Al tancar un arxiu desconnectem el seu flux. Els arxius es tanquen amb la instrucció close. Observar que la funció close
no pren arguments.
entrada.close( );
eixida.close( );

You might also like