Está en la página 1de 11

Ficheros de Texto

Usando ficheros, podemos almacenar de forma permanente un gran número de datos y


recuperarlos de forma automática. La información almacenada en un fichero no se pierde tras
la finalización del programa.

El fichero a nivel lógico consta de otros dos elementos para su gestión, que son:
-la marca de fin de fichero (EOF) que se ocupa de señalar el término del mismo
-el marcador (también llamado ventana) que señala el dato del fichero sobre el que se va
a realizar la operación de lectura o escritura.

Ventana Marca EOF

El manejo de ficheros a este nivel es sencillo: el acceso al fichero se denomina “apertura del
fichero”, este proceso puede fallar si el S. O. no encuentra el fichero en el Dispositivo de
Almacenamiento Secundario (D.A.S.) por algún motivo (no existe el fichero, el D.A.S. no está
operativo,...).
-Una vez abierto el fichero, la ventana del fichero se sitúa sobre el primer dato del fichero
y espera a que se produzca una operación de lectura o escritura.
-Dada una posición cualquiera de la ventana, ésta avanza hasta situarse en el siguiente
dato tras haber realizado una operación de lectura o escritura en la posición actual.
-Tras el procesamiento del fichero, se debe realizar una operación de “cerrar el fichero”
que asegura la actualización correcta del fichero e indica al S.O. la disponibilidad del fichero
para otro uso.
Formato de los ficheros de texto
Los ficheros de este tipo almacenan caracteres exclusivamente. ¿De qué manera
se almacenen los datos en un fichero texto?:
-Los datos se colocan en el fichero con un convenio especial (por ejemplo cada
conjunto de caracteres que forman un dato a leer, se colocan en una línea diferente,
o el conjunto de caracteres que forman un dato separados de otro conjunto
mediante un carácter blanco o un carácter tabulador,...) A este convenio, se le llama
formato del fichero.
-En la operación de lectura y escritura del fichero aparece una transformación
de tipos: del tipo original del dato a tipo carácter en la escritura, y del tipo carácter al
tipo original en la lectura. Ejemplos:
57\n Pepe Perez
45\n 22696492
39\n 1.75
21\n María Rodríguez
30\n 45632182
EOF 1.80
EOF
(A) (B)

El fichero A es un fichero texto que guarda enteros separados por un salto de línea.
Cada línea no es un entero sino un conjunto de caracteres (el ‘5’ el ‘7’ el ‘\n’) que en
su lectura debemos interpretar como un entero. En el fichero B vemos almacenadas
estructuras con tres campos, el nombre, el DNI y la talla.
Ficheros en C++
En C++ la conexión entre el código C++ y el fichero físico se realiza a través de lo que se
denomina un “stream”.Un stream es un flujo de datos entre las variables del código C++ y
el fichero físico.
Existen dos sentidos del flujo de información y a su vez, dos tipos de stream.
El flujo ifstream
se emplea para leer ficheros de texto, es decir para “importar” datos desde un
fichero texto a las variables del programa.
El flujo ofstream
se usa para escribir datos en el fichero de texto.
Para instanciar ambos tipos de flujos de datos debe incluirse la librería fstream con
#include <fstream>
Lectura de datos
Para conectar un flujo con un fichero, éste debe abrirse con el método open(). Este
método devuelve true o false según haya tenido éxito en abrirse el fichero o no.
int main(){
ifstream p;
p.open(“fichero.txt”);
if(!p)
cout << “Error abriendo el fichero para lectura << endl;
else{ //se escribe el resto de código
}
Lectura de datos
La lectura de los datos lleva implícito el conocimiento del formato en que los
datos están
almacenados en el fichero texto.
Un fichero con datos enteros uno por línea se leería como:

while(!p.eof()){ while(p>>dato){
p>> dato; //aquí se hace algo con
if(!p.eof()){ el dato
//aquí se hace algo con }
el dato}
}
Un fichero con un entero y un float en cada línea separados por blancos o
tabuladores se leería:

while(!p.eof()){ while(p>>dato_entero){
p>> dato_entero >> p>>dato_float;
dato_float; //aquí se hace algo con
if(!p.eof()){ los datos
//aquí se hace algo con }
los datos}
}
Escritura de datos en ficheros texto
El proceso es parecido al anterior, salvo que el bucle no acaba cuando se lee la
marca final de
fichero, porque ésta no existe mientras estamos escribiendo en el fichero.
La apertura tiene dos formas:
ofstream p;
p.open(“fichero.txt”);
// Esta forma crea el fichero si no existe, y si existe,
borra su contenido.

p.open(“fichero.txt”, ios::app); //Esta forma asume que el


fichero existe y respeta su contenido añadiendo datos al
final del mismo.

La escritura se produce igual que con la instrucción cout. Cada tipo de dato
(simple, vector, string, registro) se escribe en el fichero de la misma manera que
se sacaría por pantalla con un cout:
p << dato << endl;
//Escribe un dato (por ejemplo de tipo numérico) por línea
Escritura de datos en ficheros texto
Para escribir un número conocido de datos podemos usar un bucle for (por
ejemplo para escribir el
contenido de un vector v de n floats (uno por línea) escribiríamos:
for(i=0; i< n; i++)
p << v[i] << endl;
Igualmente tras la escritura de datos el fichro se debe de cerrar con
p.close();
lo que añade la
marca EOF al final de los datos introducidos y libera al fichero de su conexión con
el programa
Uso de ficheros con un vector de
registros

Uno de los usos más corrientes de los ficheros es en unión con un vector de
registros. La idea es la siguiente:
– En el fichero texto están almacenados los datos originales de los registros en
forma de una línea por campo
– El fichero se lee campo a campo, cargando los registros en un vector de
registros
– Se manipula el vector de registros (a esto se le llama manipulación en
memoria), de tal manera que sobre el vector se añaden registros, se eliminan
registros, se cambian datos de registros existentes, se buscan valores mayores,
menores , medias, de algún campo etc.
– Tras la manipulación en memoria, se guarda el contenido del vector de
registros en el fichero existente o en otro con diferente nombre.
Ejemplo de carga de un vector
de registros con ficheros
struct persona{ string nombre; int edad}; const int TAM=1000;

typedef persona grupo[TAM];

int main(){

grupo club;

int aux=0; personas_del_club.txt

persona joven, mayor; Pepe Perez


ifstream fich_in;
35
formato Maria Gonzalez
ofstream fich_out; 33
...
fich_in.open(“personas_del_club.txt”);

if(!fich_in) cout << “error abriendo fichero de lectura”<< endl;

else{ while((aux < TAM) && getline(fich_in,club[aux].nombre))

{ fich_in >> club[aux].edad; fich_in.ignore(); aux++;

fich_in.close(); //Continúa en la siguiente diapo


//Grabo en otro fichero la persona de mayor edad y la de menor edad

mayor = club[0]; joven = club[0];


for(int i=0; i < aux; i++){
if(club[i].edad > mayor.edad)
mayor = club[i];
if(club[i].edad < joven.edad)
joven = club[i];
}
fich_out.open(“joven_y_viejo.txt”); //ABRIMOS PARA ESCRITURA. (SE BORRA SI EXISTE)
if(!fich_out) cout << “error abiriendo fichero” << endl;
else{ //EN ESCRITURA NO HAY BUCLE WHILE
fich_out << mayor.nombre << endl << mayor.edad<<endl;
fich_out << joven.nombre << endl << joven.edad<<endl;
}
fich_out.close();
return 0; }
Paso de una variable ifstream u
ofstream a un subprograma
Las variables ifstream y ofstream se pueden pasar como
argumentos a subprogramas. En ese caso el paso debe ser
siempre por referencia.
Un ejemplo: Abrimos un fichero para lectura en el programa
principal y si hemos tenido éxito, se lo pasamos a un subprograma
que lo lee y saca su contenido por pantalla.
Ejemplo
void saca_fichero_por_pantalla(ifstream & fich);

int main(){
ifstream f;

f.open(“datos.txt”);
if(!f)
cout << “Error abriendo el fichero “ << endl;
else{
saca_fichero_por_pantalla(f); //Pasamos el ifstream por
referencia
f.close();
}
return 0;
}

void saca_fichero_por_pantalla(ifstream & fich){


float dato;
while(!fich.eof()){ //OJO! Aquí el fichero está ya abierto
fich >> dato;
if( !fich.eof()) //Si el dato leido no es la marca EOF
cout << num<< endl;
}
}

También podría gustarte