Vamos a centrarnos en cómo abrir y cerrar ficheros y en cómo interpretar los mensajes de error que pueden dar estas dos operaciones.
FILE
La estructura FILE
es la estructura que controla los
ficheros y se encuentra en la cabecera stdio.h
. Los flujos
utilizan estos punteros a ficheros para realizar las operaciones E/S. La
siguiente línea de código declara una variable de tipo puntero a
fichero:
FILE *ptr_fich;
En la estructura FILE
es donde se encuentra el atributo que
representa el indicador de posición de fichero.
La función fopen
abre un fichero y lo asocia a un flujo.
Necesitas especificar como argumentos el nombre de ese fichero (o la
ruta y el nombre) y el modo de apertura.
#include <stdio.h> FILE *fopen(const char *filename, const char *mode);
Aquí filename
es un puntero a char
que
referencia un string con el nombre del fichero. mode
apunta a otro string que especifica la manera en la que se va a abrir
el fichero. La función fopen
devuelve un puntero de tipo
FILE
. Si ha ocurrido algún error al abrirse, devuelve
NULL
.
El parámetro mode
es una combinación de los caracteres
r
(read, lectura), w
(write, escritura), b
(binario),
a
(append, añadir), y +
(actualizar). Si usas el caracter a
y el
fichero existe, el contenido de ese fichero se mantiene y los datos
nuevos se añaden justo al final, tras el último dato que ya estuviera
escrito (el indicador de fichero pues no está situado al inicio del
fichero, sino que en este caso está al final).
Si el fichero no existe, lo crea. Con w
es
diferente; este modo siempre borra los datos del fichero si existe (si
no, crea uno nuevo). Si al modo le añades el +
, permite
que el fichero se abra para escritura o lectura y puedes modificar
cualquier dato que hubiera en él. Si usas r
, el fichero
debe existir; si no, fopen
dará error y te devolverá
NULL
.
La siguiente lista muestra los posibles modos de abrir un fichero:
"r"
abre un fichero de texto existente para lectura.
"w"
crea un fichero de texto para escritura.
"a"
abre un fichero de texto existente para añadir datos.
"r+"
abre un fichero de texto existente para lectura o
escritura.
"w+"
crea un fichero de texto para lectura o escritura.
"a+"
abre o crea un fichero de texto para añadirle datos.
"rb"
abre un fichero binario existente para lectura.
"wb"
crea un fichero binario para escritura.
"ab"
abre un fichero binario existente para añadir datos.
"r+b"
abre un fichero binario existente para lectura
o escritura.
"w+b"
crea un fichero binario para lectura o escritura.
"a+b"
abre o crea un fichero binario para añadirle datos.
A veces podrás ver que el modo está escrito como "rb+"
en
vez de "r+b"
, por ejemplo, pero es equivalente.
Responde a las siguientes preguntas para ver si has entendido lo que se explica en este documento:
¿Qué hace la siguiente expresión?:
fopen(“text.bin”, r+b);
Después de abrir un fichero y leerlo o escribir en él, hay que
desenlazarlo del flujo de datos al que fue asociado. Esto se hace con
la función fclose
, cuya sintaxis es la siguiente:
#include <stdio.h> int fclose(FILE *stream);
Si fclose
cierra bien el fichero, devuelve
0
. Si no, la función devuelve EOF
.
Normalmente sólo falla si se ha borrado el fichero antes de intentar
cerrarlo. Acuérdate siempre de cerrar el fichero. Si no lo haces, se
pueden perder los datos almacenados en él. Además, si no lo cierras,
otros programas pueden tener problemas si lo quieren abrir más tarde.
El siguiente programa abre y cierra un fichero de texto, comprobando los posibles errores que puedan surgir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <stdio.h> enum {EXITO, FALLO}; int main(void) { FILE *ptr_fichero; char nombre_fichero[] = "resumen.txt"; int resultado = EXITO; if ( (ptr_fichero = fopen(nombre_fichero, "r") ) == NULL) { printf("No se ha podido abrir el fichero %s.\n", nombre_fichero); resultado = FALLO; } else { printf("Abierto fichero; listos para cerrarlo.\n"); if (fclose(ptr_fichero)!=0) { printf("No se ha podido cerrar el fichero %s.\n", nombre_fichero); resultado = FALLO; } } return resultado; } |
Para poder abrir un fichero dado su descriptor de fichero (
file descriptor (fd) en inglés) se ha de usar la
función fdopen
. Esta función se comporta como la función
fopen
, pero en vez de abrir un fichero dado su nombre,
usa el identificador de fichero para abrirlo:
#include <stdio.h> int fdopen(int fildes, const char *mode);
Una forma de conseguir un descriptor para un fichero es con la
función mkstemp
:
#include <stdio.h> int mkstemp(char *template);
Esta función genera un nombre de fichero temporal único a partir del
string template
. Los últimos seis caracteres de
template
deben ser “XXXXXX”
, que son
reemplazados luego por mkstemp
con una cadena que hace
que el nombre no esté repetido. Ya que será modificada,
template
no debe ser definida como constante.
La función mkstemp
devuelve el
descriptor de fichero del fichero temporal creado o -1
en
caso de error.