You are on page 1of 13

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 colección de entidades elementales o  básicas  denominadas registros que son de igual tipo y constan a su vez de diferentes entidades de nivel más  bajos  denominadas campos.            Hay dos tipos de archivos, archivos de texto y archivos binarios. Un archivo de texto es una  secuencia de  caracteres organizadas en líneas terminadas por un carácter de nueva línea.              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 tamaño 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 traducción de caracteres. Además, el número de bytes escritos  (leídos)  será el mismo que los encontrados en el dispositivo externo. Ejemplos de estos archivos son  Fotografías, imágenes,  texto con formatos, archivos ejecutables (aplicaciones), etc.            En c, un archivo es un concepto lógico 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  operación de  apertura. Una vez que el archivo está abierto, la información puede ser intercambiada entre este y el  programa.            Se puede conseguir la entrada y la salida de datos a un archivo a través 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 librería STDIO.H.      Observe que la  mayoría de las  funciones comienzan con la letra “F”, esto es un vestigio del estándar C de Unix.                       Nombre                                        Función                        fopen()     Abre un archivo. 

           El puntero a un archivo es el hilo común que unifica el sistema de E/S con buffer.  El puntero a un archivo.                        fflush()    Vacía un archivo.  Apertura de un archivo. cost charmodo).                         fputs()    Escribe una cadena en un archivo                        fseek()     Busca un byte especifico de un archivo.                               rb        Abre un archivo binario para lectura.                       fscanf()     Lee una entrada con formato desde el archivo.  . el estado y la  posición actual  del archivo.H. La cadena a la que apunta modo determina  como se abre el  archivo.                               w         Crea un archivo de texto para escritura.                               r+        Abre un archivo de texto para lectura / escritura.                               wb        Crea un archivo binario para escritura.           Donde nombre_archivo es un puntero a una cadena de caracteres que representan un nombre  valido del  archivo y puede incluir una especificación del directorio. incluyendo el nombre. En esencia identifica un archivo especifico y utiliza la secuencia asociada para dirigir el  funcionamiento  de las funciones de E/S con buffer.           La función fopen() abre una secuencia para que pueda ser utilizada y la asocia a un archivo.                      remove()      Borra un archivo.                        fprintf()   Escribe una salida con formato en el archivo. La siguiente tabla muestra los valores permitidos para modo.                               ab        Abre un archivo binario para añadir.                         fgets()    Lee una cadena de un archivo. Un puntero a un  archivo es  un puntero a una información que define varias cosas sobre él. Un puntero a un archivo es una variable de tipo puntero al tipo FILE  que se  define en STDIO. Su  prototipo es:                                FILE *fopen(const char nombre_archivo. Un programa necesita utilizar punteros a archivos para leer o escribir en los  mismos.                        ferror()    Devuelve cierto si se produce un error.                       rewind()     Coloca el localizador de posición del archivo al principio del mismo.                     fclose()     Cierra un archivo.                                a        Abre un archivo de texto para añadir.                             Modo        Significado                                r        Abre un archivo de texto para lectura. Para  obtener una variable de este tipo se utiliza una secuencia como esta:                                                           FILE *F.                          feof()    Devuelve cierto si se llega al final del archivo.

  Cierre de un archivo. fopen() devuelve un puntero nulo. la computadora lo creará.           Se puede abrir un archivo bien en modo texto o binario. incluyendo la  pérdida de  datos. si no existe. sin embargo. Este método detecto cualquier error al abrir un  archivo: como por  ejemplo disco lleno o protegido contra escritura antes de comenzar a escribir en él. Si se devuelve un valor cero  significa  . entonces se  creará. sus se abre un archivo para las operaciones de leer / escribir.           La función fclose() cierra una secuencia que fue abierta mediante una llamada a fopen(). Un error en el cierre de una secuencia puede generar todo tipo de problemas.           Donde F es el puntero al archivo devuelto por la llamada a fopen(). Estas  conversiones no  ocurren en archivos binarios.H. Si no  existe. la secuencias de retorno de carro / salto de línea se convierten a caracteres de salto de línea en  lectura. Si se usa a y no existe el archivo. entonces cualquier archivo existente con el  mismo  nombre se borrará y se crea uno nuevo. se  devolverá un  error. ocurre lo contrario: los caracteres de salto de línea se convierten en salto de línea.                              w+b        Crea un archivo binario para lectura / escritura.                              r+b        Abre un archivo binario para lectura / escritura. la  computadora no lo  borrará si existe. Escribe  toda la  información que todavía se encuentre en el buffer en el disco y realiza un cierre formal del archivo a  nivel del sistema  operativo.           La macro NULL está definida en STDIO. Finalmente. fopen()  devolverá un error. Si no existe un archivo con el mismo nombre. Un programa nunca debe alterar el valor de ese  puntero.                               a+        Añade o crea un archivo de texto para lectura / escritura. destrucción de archivos y posibles errores intermitentes en el programa. El prototipo de esta  función es:                                                      int fclose(FILE *F).           La función fopen() devuelve un puntero a archivo.                              a+b        Añade o crea un archivo binario para lectura / escritura.  Si se produce un error cuando se esta intentando abrir un archivo.  en modo  texto.                             w+        Crea un archivo de texto para lectura / escritura. Si se  quiere añadir al final del archivo entonces debe usar el modo a. La apertura de un archivo para las operaciones de lectura requiere que exista el archivo. En la mayoría de las implementaciones.           Si se usa fopen() para abrir un archivo para escritura. En la  escritura.

  excepto que  operan sobre archivo.que la operación de cierre ha tenido éxito.  Funcion feof()           Cuando se abre un archivo para entrada binaria. esta función solo falla cuando un disco se ha  retirado antes  de tiempo o cuando no queda espacio libre en el mismo. que determina cuando se ha  alcanzado el  fin del archivo leyendo datos binarios. Se puede realizar introduciendo caracteres delimitadores entre campo y  . ..           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. const char *cadena_de_control. para esto  es  necesario separarlo en campos. FILE *F). en  cualquier  otro caso.. 0.           Las funciones fgets() y fputs() pueden leer y escribir cadenas a o desde los archivos. Sus prototipos son:                                 int fprintf(FILE *F.... Generalmente. se puede leer un valor entero igual de la marca  EOF..           fprintf() y fscanf()  dirigen sus  operaciones de E/S al archivo al que apunta F. Devuelve cierto si se ha alcanzado el final del archivo.           La función puts() escribe la cadena a un archivo especifico. Esto  podría hacer que la rutina de lectura indicase una condición de fin de archivo aún cuando el fin físico  del mismo no se  haya alcanzado.           Donde F es un puntero al archivo devuelto por una llamada a fopen()..). const char *cadena_de_control.. . La función fgets() lee una cadena  desde el  archivo especificado hasta que lee un carácter de nueva línea o longitud­1 caracteres.           Algunas veces usted necesitara manipular por separado el nombre del alumno y su nota. se puede aplicar este método a archivos de texto también.           Su prototipo se encuentra en STDIO. La función tiene el siguiente prototipo:                                                       int feof(FILE *F).H. Para resolver este problema.. Por supuesto...                            Si se produce un EOF (End of File) la función gets retorna un NULL.. int long.                                 int fscanf(FILE *F.).                                          char *fgets(char *str. Los  prototipos de  estas funciones son:                                                char *fputs(char *str. FILE *F). C incluye la función feof().           Ahora bien para el ejemplo anterior usted incluirá los datos de la forma:                                                   Nombre del alumno1 nota                                                   Nombre del alumno2 nota                                                               .

.  Argumentos de Línea de Comando C provee un mecanismo para pasar argumentos desde la línea de comandos al programa que se va a  ejecutar. Si no un valor distinto de cero.. Su  prototipo es:                                                     void rewind (FILE *F). Su prototipo es:                                                     int fflush(FILE *F).campo.. El contador es llamdo por convención  argc y el apuntador argv.          Devuelve cero si tiene éxito. Su prototipo es el siguiente:                                            int remove(char *nombre_archivo). por  ejemplo:                                              fprinft(C. devuelve falso. Dado que argv es un apundador a un  .H          La función remove() borra el archivo especificado.           Donde F es un puntero a un archivo válido.  Esto generara un archivo de tipo:                                                   Nombre del alumno1. El uso de de argv es un poco truculento. Devuelve cierto si se ha producido un error durante la  ultima  operación sobre el archivo.  Esta  función devuelve cero si tiene éxito.nota                                                               .nota                                                   Nombre del alumno2.          Si se llama esta función con un puntero nulo se vacian los buffers de todos los archivos abiertos.          Donde F es un puntero a un archivo válido. Esta función se encuentra en STDIO. la rutina main es llamada con dos argumentos: un  contador y un apuntador a un arreglo de cadenas de caracteres. se debe llamar a ferror() inmediatamente después de la operación de  este tipo. Esta función se encuentra en STDIO. al principio del archivo. Su  prototipo  es:                                                     int ferror(FILE *F). devuelve EOF. en otro caso. indicado por su  argumento.nombre.H          La función ferror() determina si se ha producido en error en una operación sobre un archivo.     En caso contrario.”%s. el error puede perderse. si no  se ase así.. Debido a que cada operación sobre el  archivo  actualiza la condición de error.%d \n”. Cuando el programa comieza su ejecución.          La función fflush() escribe todos los datos almacenados en el buffer sobre el archivo asociado con  un  apuntador.           La función rewind() inicializa el indicador de posición.cal).

fprintf("The program name is %s\n". . char **argv ) { FILE *fp.arreglo de cadenas de caracteres. Los  parámetros 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.argv[0]).argv[i]). el nombre del programa mas dos argumentos que corresponderian  a los nombres de los archivos fuente y destino. El valor de retorno es un número no negativo o EOF en caso de error. y así  sucesivamente. } fputs La función fputs escribe una cadena en un fichero.h> int main ( int argc. i < argc. #include <stdio. Esto es. Los  argumentos comienzan realmente con argv[1].  Un ejemplo de llamada de un programa llamado copia.  La segunda cadena is referenciada por argv[1] (o *(argv + 1)). argc). i++) { fprintf("%s". la tercera por argv[2].txt. for (i = 1.h> int main(int argc. la primera cadena de caracteres es referenciada por argv[0] (o *argv). contiene el nombre del programa. La primera cadena de caracteres. Veamos un ejemplo que simplemente muestra los argumentos de un programa. argv[0]. char *argv[]) { int i. No se añade el carácter de retorno de línea ni el  carácter nulo final.txt destino. fprintf("The number of command line arguments is %d\n". } fprintf("\n"). FILE *archivo) para ver su funcionamiento mostramos el siguiente ejemplo: #include <stdio. return 0. que copie un archivo en otro archivo seria:  copia fuente.

\n". fclose ( fp ). fputs La función fputs escribe una cadena en un fichero.txt".char cadena[] = "Mostrando el uso de fputs en un fichero. fgets Esta función está diseñada para leer cadenas de caracteres. fputs( cadena.\n". Los  parámetros de entrada son la cadena a escribir y un puntero a la estructura FILE del fichero donde se  realizará la escritura. Leerá hasta n­1 caracteres o hasta que lea un  retorno de línea. El prototipo correspondiente de fgets es: . el carácter de retorno de línea también es leído. No se añade el carácter de retorno de línea ni el  carácter nulo final. } return 0. } return 0. FILE *archivo) para ver su funcionamiento mostramos el siguiente ejemplo: #include <stdio. char cadena[] = "Mostrando el uso de fputs en un fichero.h> int main ( int argc. fp = fopen ( "fichero. fp = fopen ( "fichero.txt". El valor de retorno es un número no negativo o EOF en caso de error. El prototipo correspondiente de fputs es: int fputs(const char *buffer. fp ). fclose ( fp ). "r+" ). fputs( cadena. char **argv ) { FILE *fp. En este último caso. fp ). "r+" ).

 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 tamaño o hasta que encuentre el final de una linea (\n) o hasta que encuentre el final del  archivo (EOF).caracteres). printf("%s". printf("\nEl contenido del archivo de prueba es \n\n"). char caracteres[100]. #include <stdio."r"). while (feof(archivo) == 0) { fgets(caracteres. Este es el mismo ejemplo de antes con la diferencia de que este hace uso de fgets en lugar de fgetc. El prototipo correspondiente de fprintf es: int fprintf(FILE *archivo. El primer parámetro buffer lo hemos llamado así porque es un puntero a un espacio de memoria del  tipo char (podríamos usar un arreglo de char).h> int main() { FILE *archivo. Y por ultimo el puntero del archivo por supuesto que  es la forma en que fgets sabra a que archivo debe leer. El beneficio de esta función es que se puede obtener una linea completa a la vez.h> #include <stdlib. . FILE *archivo).. archivo = fopen("prueba. argumento. La  función fgets se comporta de la siguiente manera.). . if (archivo == NULL) exit(1). Y resulta muy útil  para algunos fines como la construcción de un parser de algún tipo de archivo de texto.. El segundo parámetro es tamaño que es el limite en  cantidad de caracteres a leer para la funcion fgets.100. En este ejemplo no vamos a profundizar mas que para decir que caracteres es un buffer. } } return 0.txt". const char *formato.  los pormenores seran explicados en la sección de manejo dinámico de memoria. int tamaño.char *fgets(char *buffer. fprintf La función fprintf funciona igual que printf en cuanto a parámetros. pero la salida se dirige a un  fichero en lugar de a la pantalla.archivo).

 abrimos el documento "fichero..Podemos ver un ejemplo de su uso. char buffer[100]. fscanf(fp.h> int main ( int argc.".txt" en modo lectura/escritura y  escribimos dentro de el. char **argv ) { FILE *fp. printf("%s". char **argv ) { FILE *fp. fp = fopen ( "fichero. fp = fopen ( "fichero. pero la entrada se toma de un  fichero en lugar del teclado. Podemos ver un ejemplo de su uso. El prototipo correspondiente de fscanf es: int fscanf(FILE *fichero. fprintf(fp. char buffer[100] = "Esto es un texto dentro del fichero.buffer).txt". "r" ). . argumento.txt". fclose ( fp )."). } . "r+" ).txt" en modo lectura y leyendo  dentro de el. "\nEsto es otro texto dentro del fichero. "%s". abrimos el documento "fichero.). #include <stdio. fscanf La función fscanf funciona igual que scanf en cuanto a parámetros. "%s" . #include <stdio.h> int main ( int argc. return 0. const char *formato. fclose ( fp ). buffer).buffer).. fprintf(fp. } return 0.

 FILE * stream ). size_t cantidad. PARAMETROS: ptr  : Puntero a un bloque de memoria con un tamaño mínimo de (size*count) bytes. cada uno de los cuales tiene un tamaño definido por "size". size_t tamano. FILE *archivo). Es  capaz de escribir hacia un fichero uno o varios registros de la misma longitud almacenados a partir de  una dirección de memoria determinada.  fread size_t fread ( void * ptr. size  : Tamaño en bytes de cada elemento (de los que voy a leer). fwrite Esta función está pensada para trabajar con registros de longitud constante y forma pareja con fread. Si esto es exitoso la cantidad de bytes leídos es (size*count). que especifica la cadena de entrada. count : Número de elementos. El prototipo correspondiente de fwrite es: size_t fwrite(void *puntero. Los parámetros son: un puntero a la zona de memoria de donde se obtendrán los  datos a escribir. Luego los guarda en el bloque de  memoria especificado por "ptr". el número de registros a escribir y un puntero a la  estructura FILE del fichero al que se hará la escritura. el tamaño de cada registro. Un ejemplo concreto del uso de fwrite con su contraparte fread y usando funciones es: /* . no el  número de bytes. size_t size. stream: Puntero a objetos FILE. los cuales tienen un tamaño "size". El valor de retorno es el número de registros escritos. size_t count. Efectúa la lectura de un arreglo de elementos  "count". El indicador de posición de la cadena de caracteres avanza hasta leer la  totalidad de bytes. Esta función lee un bloque de una "stream" de datos.

case 2: break. int Edad. Insertar datos"). InsertarDatos(FILE *Fichero). VerDatos(FILE *Fichero).h> void void void void menu(). return 0. Crear fichero"). VerDatos(fichero). } InsertarDatos(fichero). int main(int argc. case 4: exit = 1. } } void menu() { printf("\nMenu:"). while (!exit) { menu(). scanf("%d". default: printf("\nopcion no valida"). char** argv) { int opcion.* * * * */ FicheroCompleto.c Copyright 2009 Julio César Brizuela <brizuela@linux-qxlk> #include <stdio. int exit = 0. &opcion). struct sRegistro { char Nombre[25]. break. CrearFichero(FILE *Fichero). } registro. FILE *fichero. printf("\nOpcion: "). float Sueldo. case 3: break. . printf("\n\t2. switch(opcion) { case 1: break. printf("\n\t1. CrearFichero(fichero).

fwrite(&registro. "r"). Fichero). scanf("%d". return. &registro.Sueldo). } void VerDatos(FILE *Fichero) { int numero = 1. &registro. return.Edad). return. } fclose (Fichero). void CrearFichero(FILE *Fichero) { Fichero = fopen("fichero". printf("\nDigita el sueldo: ").Nombre). "w"). scanf("%f". scanf("%s". fclose(Fichero). printf("\nArchivo creado!"). 1. sizeof(struct sRegistro). } void InsertarDatos(FILE *Fichero) { Fichero = fopen("fichero". "r"). "a+"). Ver datos"). } printf("\nDigita el nombre: "). if(Fichero == NULL) { printf("\nFichero no existe! \nPor favor creelo").} printf("\n\t3. if(Fichero == NULL) { printf("\nFichero no existe! \nPor favor creelo"). . printf("\n\t4. if(!Fichero) { Fichero = fopen("fichero". Fichero = fopen("fichero". printf("\nDigita la edad: "). Salir"). } else { printf("\nEl fichero ya existe!"). registro.

} fclose(Fichero).2f". sizeof(struct sRegistro).Edad. while(!feof(Fichero)) { printf("\n%d \t%s \t%d \t%. numero++. numero. printf("\nNumero \tNombre \tEdad \tSueldo"). registro. Fichero). registro.Nombre. 1. 1. sizeof(struct sRegistro). } fread(&registro. [editar]  . Fichero). } return. fread(&registro. registro.Sueldo).return.