Está en la página 1de 12

7. Manejo de Archivos en C.

Los datos que hemos tratado hasta el momento han residido en la memoria principal. Sin
embargo, las grandes cantidades de datos se almacenan normalmente en un dispositivo de memoria
secundaria. Estas colecciones de datos se conocen como archivos (antiguamente ficheros). Un
archivo es un conjunto de datos estructurados en una coleccin de entidades elementales o bsicas
denominadas registros que son de igual tipo y constan a su vez de diferentes entidades de nivel ms
bajos denominadas campos o miembros.

Hay dos tipos de archivos, archivos de texto y archivos binarios. Un archivo de texto es una
secuencia de caracteres organizadas en lneas terminadas por un carcter de nueva lnea. En estos
archivos se pueden almacenar canciones, fuentes de programas, base de datos simples, etc. Los archivos
de texto se caracterizan por ser planos, es decir, todas las letras tienen el mismo formato y no hay
palabras subrayadas, en negrita, o letras de distinto tamao o ancho.

Un archivo binario es una secuencia de bytes que tienen una correspondencia uno a uno con un
dispositivo externo. As que no tendr lugar ninguna traduccin de caracteres. Adems, el nmero de
bytes escritos (ledos) ser el mismo que los encontrados en el dispositivo externo. Ejemplos de estos
archivos son Fotografas, imgenes, texto con formatos, archivos ejecutables (aplicaciones), etc.

En C, un archivo es un concepto lgico que puede aplicarse a muchas cosas desde archivos de disco
hasta terminales o una impresora. Se asocia una secuencia con un archivo especifico realizando una
operacin de apertura. Una vez que el archivo est abierto, la informacin puede ser intercambiada
entre este y el programa.
Se puede conseguir la entrada y la salida de datos a un archivo a travs del uso de la biblioteca de
funciones; C no tiene palabras claves que realicen las operaciones de E/S. La siguiente tabla da un
breve resumen de las funciones que se pueden utilizar. Se debe incluir la librera stdio.h. Observe que
la mayora de las funciones comienzan con la letra f, esto es un vestigio del estndar C de Unix.
Nombre Funcin
fopen() Abre un archivo.
fclose() Cierra un archivo.
getc() lee un carcter del archivo
putc() Escribe un carcter en el archivo
fgets() Lee una cadena de un archivo.
fputs() Escribe una cadena en un archivo
fseek() Busca un byte especifico de un archivo.
fprintf() Escribe una salida con formato en el archivo.
fscanf() Lee una entrada con formato desde el archivo.
feof() Devuelve cierto si se llega al final del archivo.
ferror() Devuelve cierto si se produce un error.
rewind() Coloca el localizador de posicin del archivo al principio del mismo.
remove() Borra un archivo.
fflush() Vaca un archivo.
El puntero a un archivo.
El puntero a un archivo es el hilo comn que unifica el sistema de E/S con buffer. Un puntero a un
archivo es un puntero a una informacin que define varias cosas sobre l, incluyendo el nombre, el
estado y la posicin actual del archivo. En esencia identifica un archivo especfico y utiliza la secuencia
asociada para dirigir el funcionamiento de las funciones de E/S con buffer. Un puntero a un archivo es
una variable de tipo puntero al tipo FILE que se define en stdio.h. Un programa necesita utilizar
punteros a archivos para leer o escribir en los mismos. Para obtener una variable de este tipo se utiliza
una secuencia como esta:
FILE *f;
Apertura de un archivo.
La funcin fopen() abre una secuencia para que pueda ser utilizada y la asocia a un archivo. Su
prototipo es:
FILE *fopen(const char nombre_archivo, cost charmodo);
Donde nombre_archivo es un puntero a una cadena de caracteres que representan un nombre
valido del archivo y puede incluir una especificacin del directorio. La cadena a la que apunta modo
determina como se abre el archivo. La siguiente tabla muestra los valores permitidos para modo.
Modo Significado
r Abre un archivo de texto para lectura.
w Crea un archivo de texto para escritura.
a Abre un archivo de texto para aadir.
rb Abre un archivo binario para lectura.
wb Crea un archivo binario para escritura.
ab Abre un archivo binario para aadir.
r+ Abre un archivo de texto para lectura / escritura.
w+ Crea un archivo de texto para lectura / escritura.
a+ Aade o crea un archivo de texto para lectura / escritura.
r+b Abre un archivo binario para lectura / escritura.
w+b Crea un archivo binario para lectura / escritura.
a+b Aade o crea un archivo binario para lectura / escritura.
La funcin fopen() devuelve un puntero a archivo. Un programa nunca debe alterar el valor de ese
puntero.
Si se produce un error cuando se esta intentando abrir un archivo, fopen() devuelve un puntero nulo.
Se puede abrir un archivo bien en modo texto o binario. En la mayora de las implementaciones,
en modo texto, la secuencias de retorno de carro / salto de lnea se convierten a caracteres de salto de
lnea en lectura. En la escritura, ocurre lo contrario: los caracteres de salto de lnea se convierten en
salto de lnea. Estas conversiones no ocurren en archivos binarios.
La macro NULL est definida en stdio.h. Este mtodo detecta cualquier error al abrir un archivo:
como por ejemplo disco lleno o protegido contra escritura antes de comenzar a escribir en l.
Si se usa fopen() para abrir un archivo para escritura, entonces cualquier archivo existente con el
mismo nombre se borrar y se crea uno nuevo. Si no existe un archivo con el mismo nombre, entonces
se crear. Si se quiere aadir al final del archivo entonces debe usar el modo a. Si se usa a y no existe el
archivo, se devolver un error. La apertura de un archivo para las operaciones de lectura requiere que
exista el archivo. Si no existe, fopen() devolver un error. Finalmente, si se abre un archivo para las
operaciones de leer / escribir, la computadora no lo
borrar si existe; sin embargo, si no existe, la computadora lo crear.
Cierre de un archivo.
La funcin fclose() cierra una secuencia que fue abierta mediante una llamada a fopen(). Escribe
toda la informacin que todava se encuentre en el buffer en el disco y realiza un cierre formal del
archivo a nivel del sistema operativo. Un error en el cierre de una secuencia puede generar todo tipo de
problemas, incluyendo la prdida de datos, destruccin de archivos y posibles errores intermitentes en
el programa. El prototipo de esta funcin es:
int fclose(FILE *F);
Donde F es el puntero al archivo devuelto por la llamada a fopen(). Si se devuelve un valor cero
significa que la operacin de cierre ha tenido xito. Generalmente, esta funcin solo falla cuando un
disco se ha retirado antes de tiempo o cuando no queda espacio libre en el mismo.
Para introducir u obtener datos de un archivo tenemos las siguientes cuatro funciones:
fprintf() y fscanf()

Estas funciones se comportan exactamente como prinft() y scanf() discutidas anteriormente,
excepto que operan sobre archivo. Sus prototipos son:
int fprintf(FILE *F, const char *cadena_de_control, .....);
int fscanf(FILE *F, const char *cadena_de_control, .....);
Donde F es un puntero al archivo devuelto por una llamada a fopen(). fprintf() y fscanf() dirigen
sus operaciones de E/S al archivo al que apunta F.
Las funciones fgets() y fputs() pueden leer y escribir cadenas a o desde los archivos. Los
prototipos de estas funciones son:
char *fputs(char *str, FILE *F);
char *fgets(char *str, int long, FILE *F);
La funcin puts() escribe la cadena a un archivo especifico. La funcin fgets() lee una cadena
desde el archivo especificado hasta que lee un carcter de nueva lnea o longitud-1 caracteres.
Si se produce un EOF (End of File) la funcin gets retorna un NULL.
Funcion feof()
Cuando se abre un archivo para entrada binaria, se puede leer un valor entero igual de la marca
EOF. Esto podra hacer que la rutina de lectura indicase una condicin de fin de archivo an cuando el
fin fsico del mismo no se haya alcanzado. Para resolver este problema, C incluye la funcin feof(), que
determina cuando se ha alcanzado el fin del archivo leyendo datos binarios. La funcin tiene el
siguiente prototipo:
int feof(FILE *F);
Su prototipo se encuentra en stdio.h. Devuelve cierto si se ha alcanzado el final del archivo, en
cualquier otro caso, 0. Por supuesto, se puede aplicar este mtodo a archivos de texto tambin.
Ahora bien para el ejemplo anterior usted incluir los datos de la forma:
Nombre del alumno1 nota
Nombre del alumno2 nota
.....
Algunas veces usted necesitara manipular por separado el nombre del alumno y su nota, para esto
es necesario separarlo en campos. Se puede realizar introduciendo caracteres delimitadores entre campo
y campo, por ejemplo:
fprinft(C,%s;%d n,nombre,cal);
Esto generara un archivo de tipo:
Nombre del alumno1;nota
Nombre del alumno2;nota
.....
La funcin rewind() inicializa el indicador de posicin, al principio del archivo, indicado por su
argumento. Su
prototipo es:
void rewind (FILE *F);
Donde F es un puntero a un archivo vlido. Esta funcin se encuentra en STDIO.H
La funcin ferror() determina si se ha producido en error en una operacin sobre un archivo. Su
prototipo
es:
int ferror(FILE *F);
Donde F es un puntero a un archivo vlido. Devuelve cierto si se ha producido un error durante la
ultima
operacin sobre el archivo. En caso contrario, devuelve falso. Debido a que cada operacin sobre el
archivo
actualiza la condicin de error, se debe llamar a ferror() inmediatamente despus de la operacin de
este tipo; si no
se ase as, el error puede perderse. Esta funcin se encuentra en STDIO.H
La funcin remove() borra el archivo especificado. Su prototipo es el siguiente:
int remove(char *nombre_archivo);
Devuelve cero si tiene xito. Si no un valor distinto de cero.
La funcin fflush() escribe todos los datos almacenados en el buffer sobre el archivo asociado con
un
apuntador. Su prototipo es:
int fflush(FILE *F);
Si se llama esta funcin con un puntero nulo se vacian los buffers de todos los archivos abiertos.
Esta
funcin devuelve cero si tiene xito, en otro caso, devuelve EOF.
Argumentos de Lnea de Comando
C provee un mecanismo para pasar argumentos desde la lnea de comandos al programa que se va a
ejecutar. Cuando el programa comieza su ejecucin, la rutina main es llamada con dos argumentos: un
contador y un apuntador a un arreglo de cadenas de caracteres. El contador es llamdo por convencin
argc y el apuntador argv. El uso de de argv es un poco truculento. Dado que argv es un apundador a un
arreglo de cadenas de caracteres, la primera cadena de caracteres es referenciada por argv[0] (o *argv).
La segunda cadena is referenciada por argv[1] (o *(argv + 1)), la tercera por argv[2], y as
sucesivamente. La primera cadena de caracteres, argv[0], contiene el nombre del programa. Los
argumentos comienzan realmente con argv[1].
Un ejemplo de llamada de un programa llamado copia, que copie un archivo en otro archivo seria:
copia fuente.txt destino.txt. Esto es, el nombre del programa mas dos argumentos que corresponderian
a los nombres de los archivos fuente y destino.
Veamos un ejemplo que simplemente muestra los argumentos de un programa.
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
fprintf("The number of command line arguments is %dn", argc);
fprintf("The program name is %sn",argv[!]);
for (i " #; i $ argc; i%%) {
fprintf("%s",argv[i]);
&
fprintf("n");
return !;
&
fputs
La funcin fputs escribe una cadena en un fichero. No se aade el carcter de retorno de lnea ni el
carcter nulo final. El valor de retorno es un nmero no negativo o EOF en caso de error. Los
parmetros de entrada son la cadena a escribir y un puntero a la estructura FILE del fichero donde se
realizar la escritura.
El prototipo correspondiente de fputs es:
int fputs(const char *buffer, FILE *archivo)
para ver su funcionamiento mostramos el siguiente ejemplo:
#include <stdio.h>

int main ( int arc, char **arv )
!
FILE *fp"

char cadena#$ % &'ostrando el uso de fputs en un fichero.(n&"

fp % fopen ( &fichero.t)t&, &r*& )"

fputs( cadena, fp )"

fclose ( fp )"

return +"
,
fputs
La funcin fputs escribe una cadena en un fichero. No se aade el carcter de retorno de lnea ni el
carcter nulo final. El valor de retorno es un nmero no negativo o EOF en caso de error. Los
parmetros de entrada son la cadena a escribir y un puntero a la estructura FILE del fichero donde se
realizar la escritura.
El prototipo correspondiente de fputs es:
int fputs(const char *buffer, FILE *archivo)
para ver su funcionamiento mostramos el siguiente ejemplo:
#include <stdio.h>

int main ( int arc, char **arv )
!
FILE *fp"

char cadena#$ % &'ostrando el uso de fputs en un fichero.(n&"

fp % fopen ( &fichero.t)t&, &r*& )"

fputs( cadena, fp )"

fclose ( fp )"

return +"
,
fgets
Esta funcin est diseada para leer cadenas de caracteres. Leer hasta n-1 caracteres o hasta que lea un
retorno de lnea. En este ltimo caso, el carcter de retorno de lnea tambin es ledo.
El prototipo correspondiente de fgets es:
char *fets(char *buffer, int tama-o, FILE *archivo)"
El primer parmetro buffer lo hemos llamado as porque es un puntero a un espacio de memoria del
tipo char (podramos usar un arreglo de char). El segundo parmetro es tamao que es el limite en
cantidad de caracteres a leer para la funcion fgets. Y por ultimo el puntero del archivo por supuesto que
es la forma en que fgets sabra a que archivo debe leer.
#include <stdio.h>
#include <stdlib.h>

int main()
!
FILE *archivo"

char caracteres#.++$"

archivo % fopen(&prueba.t)t&,&r&)"

if (archivo %% /0LL)
e)it(.)"

printf(&(nEl contenido del archivo de prueba es (n(n&)"
1hile (feof(archivo) %% +)
!
fets(caracteres,.++,archivo)"
printf(&2s&,caracteres)"
,

return +"
,
Este es el mismo ejemplo de antes con la diferencia de que este hace uso de fgets en lugar de fgetc. La
funcin fgets se comporta de la siguiente manera, leer del archivo apuntado por archivo los caracteres
que encuentre y a ponerlos en buffer hasta que lea un caracter menos que la cantidad de caracteres
especificada en tamao o hasta que encuentre el final de una linea (\n) o hasta que encuentre el final del
archivo (EOF). En este ejemplo no vamos a profundizar mas que para decir que caracteres es un buffer,
los pormenores seran explicados en la seccin de manejo dinmico de memoria.
El beneficio de esta funcin es que se puede obtener una linea completa a la vez. Y resulta muy til
para algunos fines como la construccin de un parser de algn tipo de archivo de texto.
fprintf
La funcin fprintf funciona igual que printf en cuanto a parmetros, pero la salida se dirige a un
fichero en lugar de a la pantalla.
El prototipo correspondiente de fprintf es:
int fprintf(FILE *archivo, const char *formato, arumento, ...)"
Podemos ver un ejemplo de su uso, abrimos el documento "fichero.txt" en modo lectura/escritura y
escribimos dentro de el.
#include <stdio.h>

int main ( int arc, char **arv )
!
FILE *fp"

char buffer#.++$ % &Esto es un te)to dentro del fichero.&"

fp % fopen ( &fichero.t)t&, &r*& )"

fprintf(fp, buffer)"
fprintf(fp, &2s&, &(nEsto es otro te)to dentro del fichero.&)"

fclose ( fp )"

return +"
,
fscanf
La funcin fscanf funciona igual que scanf en cuanto a parmetros, pero la entrada se toma de un
fichero en lugar del teclado.
El prototipo correspondiente de fscanf es:
int fscanf(FILE *fichero, const char *formato, arumento, ...)"
Podemos ver un ejemplo de su uso, abrimos el documento "fichero.txt" en modo lectura y leyendo
dentro de el.
#include <stdio.h>


int main ( int arc, char **arv )
!
FILE *fp"

char buffer#.++$"

fp % fopen ( &fichero.t)t&, &r& )"

fscanf(fp, &2s& ,buffer)"
printf(&2s&,buffer)"

fclose ( fp )"

return +"
,

fread
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
Esta funcin lee un bloque de una "stream" de datos. Efecta la lectura de un arreglo de elementos
"count", cada uno de los cuales tiene un tamao definido por "size". Luego los guarda en el bloque de
memoria especificado por "ptr". El indicador de posicin de la cadena de caracteres avanza hasta leer la
totalidad de bytes. Si esto es exitoso la cantidad de bytes ledos es (size*count).
PARAMETROS:
ptr : Puntero a un bloque de memoria con un tamao mnimo de (size*count) bytes.
size : Tamao en bytes de cada elemento (de los que voy a leer).
count : Nmero de elementos, los cuales tienen un tamao "size".
stream: Puntero a objetos FILE, que especifica la cadena de entrada.
fwrite
Esta funcin est pensada para trabajar con registros de longitud constante y forma pareja con fread. Es
capaz de escribir hacia un fichero uno o varios registros de la misma longitud almacenados a partir de
una direccin de memoria determinada. El valor de retorno es el nmero de registros escritos, no el
nmero de bytes. Los parmetros son: un puntero a la zona de memoria de donde se obtendrn los datos
a escribir, el tamao de cada registro, el nmero de registros a escribir y un puntero a la estructura
FILE del fichero al que se har la escritura.
El prototipo correspondiente de fwrite es:
si3e4t f1rite(void *puntero, si3e4t tamano, si3e4t cantidad, FILE
*archivo)"
Un ejemplo concreto del uso de fwrite con su contraparte fread y usando funciones es:
5*
* Fichero6ompleto.c
*
* 6op7riht 8++9 :ulio 6;sar <ri3uela <bri3uela=linu)>?)l@>
*
*5

#include <stdio.h>

void menu()"
void 6rearFichero(FILE *Fichero)"
void InsertarAatos(FILE *Fichero)"
void BerAatos(FILE *Fichero)"

struct sCeistro !
char /ombre#8D$"
int Edad"
float Eueldo"
, reistro"

int main(int arc, char** arv)
!
int opcion"
int e)it % +"
FILE *fichero"

1hile (Fe)it)
!
menu()"
printf(&(nGpcionH &)"
scanf(&2d&, Iopcion)"

s1itch(opcion)
!
case .H
6rearFichero(fichero)"
brea@"
case 8H
InsertarAatos(fichero)"
brea@"
case JH
BerAatos(fichero)"
brea@"
case KH
e)it % ."
brea@"
defaultH
printf(&(nopcion no valida&)"
,
,

return +"
,

void menu()
!
printf(&(n'enuH&)"
printf(&(n(t.. 6rear fichero&)"
printf(&(n(t8. Insertar datos&)"
printf(&(n(tJ. Ber datos&)"
printf(&(n(tK. Ealir&)"
,

void 6rearFichero(FILE *Fichero)
!
Fichero % fopen(&fichero&, &r&)"

if(FFichero)
!
Fichero % fopen(&fichero&, &1&)"
printf(&(nLrchivo creadoF&)"
,
else
!
printf(&(nEl fichero 7a e)isteF&)"
,

fclose (Fichero)"

return"
,

void InsertarAatos(FILE *Fichero)
!
Fichero % fopen(&fichero&, &a*&)"

if(Fichero %% /0LL)
!
printf(&(nFichero no e)isteF (nMor favor creelo&)"
return"
,

printf(&(nAiita el nombreH &)"
scanf(&2s&, reistro./ombre)"

printf(&(nAiita la edadH &)"
scanf(&2d&, Ireistro.Edad)"

printf(&(nAiita el sueldoH &)"
scanf(&2f&, Ireistro.Eueldo)"

f1rite(Ireistro, si3eof(struct sCeistro), ., Fichero)"

fclose(Fichero)"

return"
,

void BerAatos(FILE *Fichero)
!
int numero % ."

Fichero % fopen(&fichero&, &r&)"

if(Fichero %% /0LL)
!
printf(&(nFichero no e)isteF (nMor favor creelo&)"
return"
,

fread(Ireistro, si3eof(struct sCeistro), ., Fichero)"

printf(&(n/umero (t/ombre (tEdad (tEueldo&)"

1hile(Ffeof(Fichero))
!
printf(&(n2d (t2s (t2d (t2.8f&, numero, reistro./ombre,
reistro.Edad, reistro.Eueldo)"
fread(Ireistro, si3eof(struct sCeistro), ., Fichero)"
numero**"
,

fclose(Fichero)"

return"
,
[editar]

También podría gustarte