Entrada y Salida de Archivos
Download
Report
Transcript Entrada y Salida de Archivos
Programación Científica
Dr. Romeo Sánchez Nigenda.
E-mail: [email protected]
http://yalma.fime.uanl.mx/~romeo/
Oficina: 1er. Piso del CIDET. Oficina con Dr. Oscar Chacón
Horas de Tutoría: 10am-11am Martes y Jueves
Website: http://yalma.fime.uanl.mx/~romeo/
Sesiones: 48
* Slides aumentados con información de Dr. Roger Ríos, y Dr.
Fernando López
Temario:
1.
2.
3.
4.
5.
6.
7.
40% Proyecto
30% Examen Parcial
30% Examen Final
10% Participación
Fundamentos de Programación en C
Apuntadores y Funciones
Arreglos y Estructuras
Manejo de Memoria
Recursividad
Entrada y Salida de Archivos
Desarrollo y Depuración de Proyecto de
Programación
Total a calificar: 110 puntos!
Material de apoyo:
A. KELLY, I. POHL. A Book on C. Addison-Wesley, Reading, EUA, 1998.
2. B. KERNIGHAN, D. RITCHIE. The C Programming Language. Prentice Hall,
Second Edition, 1988.
3. D. KNUTH. The Art of Computer Programming. Addison Wesley, 1998.
4. H. DEITEL, P. DEITEL. Como Programar en C/C++. Prentice Hall, Segunda
Edición. 1995.
5. L. Joyanes, I. Zahonero. Programación en C - Metodología, Algoritmos y Estructura de
Datos. McGraw Hill-Interamericana, 2006.
6. B. Stroustrup. The C++ Programming Language. Addison Wesley. Third Edition.
1997.
Software:
Compiladores GCC (GNU Compiler Collection)
IDEs (Integrated Development Environment):
http://www.eclipse.org/downloads/
http://kdevelop.org/
http://www.bloodshed.net/devcpp.html
Entradas y Salidas por
Archivos
Objetivo General: Aprender a utilizar las características
típicas de los mecanismos de Entrada y Salida para
archivos en C, así como las funciones de acceso más
utilizadas.
Preliminares
Lectura: Es la operación de introducir (leer) datos al
sistema.
◦ Se realiza usualmente desde el teclado, el disco, o cualquier
otro dispositivo de entrada
Escritura: Se relaciona a la operación de generar
datos por el sistema.
◦ Se realiza usando cualquier dispositivo de salida como
monitor o impresora.
En C las funciones para entrada y salida están
incorporadas como Biblioteca de Ejecución.
◦ stdio.h: proporciona tipos de datos, macros y funciones
para acceder a archivos.
◦ El manejo de archivos se hace a través de flujos (streams) o
canales, que conducen los datos entre el programa en
ejecución y los dispositivos externos.
Flujos
Un flujo (stream) es una abstracción que refiere
a una corriente de datos entre un origen o
fuente (productor) y un destino (consumidor).
Entre el origen y destino debe existir una
conexión o canal (pipe) por donde circulan los
datos.
Por ejemplo:
extern FILE *stdout;
◦ Es el flujo que asocia la salida estándar (pantalla) con
el programa. Cuando ejecutamos:
printf(“Ejemplo en clase.”);
◦ Se escriben los datos en stdout, es decir, en pantalla.
Punteros FILE
Los archivos se ubican en dispositivos externos, y se
utilizan buffers para accesarlos:
Dentro del programa, se hace referencia a los archivos
usando punteros a una estructura predefinida: FILE
FILE contiene información sobre el archivo tal como la
dirección del buffer que utiliza, su modo de apertura,
etc. FILE se encuentra en stdio.h.
Ejemplos:
Declaración de punteros a FILE:
FILE * pfile;
FILE * stdin, stdout;
En funciones:
FILE * escribir(FILE *);
Apertura de archivos: Conexión del archivo externo
con el programa en un determinado modo (e.g.,
binario, de texto). Se utiliza la función:
FILE * fopen(const char * nombre_archivo, const char * modo)
Ejemplo:
char nombre_archivo = “C:\test.txt”;
FILE * pfile = fopen(nombre_archivo, “r”);
if(pfile==NULL)
puts(“ERROR al abrir el archivo…”);
Modos de apertura de un archivo
Modo
Descripción
r
Abre para lectura
w
Crea un archivo nuevo, si existe se pierden sus datos
a
Abre para añadir al final del archivo
r+
Abre archivo existente para leer o escribir
w+
Crea un archivo para leer o escribir, si existe se pierden sus datos
a+
Abre archivo para leer o escribir al final. Si no existe es como w+
Tipo de archivos:
Texto: Se utiliza una “t” al final, e.g., “rt”, “a+t”
Binario: Se utiliza una “b”, eg., “rb”, “w+b”.
Cierre de archivos
Los archivos en C trabajan con una memoria
intermedia conocida como buffer.
La entrada y salida de datos se almacenan en ese
buffer, vaciándose a los archivos cuando están
llenos.
Al terminar la ejecución del programa se tienen
que cerrar los archivos para que cualquier dato
en los buffers se vacíe a los archivos.
int fclose (FILE * pfile)
Devuelve EOF si hay un error al cerrar. Es una macro
definida en stdio.h para indicar que se ha leído el fin del
archivo.
Manejo de archivos secuenciales
Las funciones de E/S de archivos tienen mucho parecido con las funciones de E/S
para los flujos stdin (teclado) y stdout (pantalla): printf, scanf, getchar, putchar, gets,
puts, putc, getc antecediendo la letra f, ejemplo: fprintf, fscanf, fputc, fgetc, etc.
Ejemplo: Crea un archivo de texto con caracteres introducidos desde teclado,
utiliza enter para parar.
char * nfile = "test.txt";
FILE * pf = fopen(nfile,"w+t");
if(pf==NULL){
puts("Error al abrir archivo!");
exit(0);
}else{
int c;
do{
c=getchar();
fputc(c,pf);
}while(c!='\n');
fclose(pf);
}
Manejo de archivos secuenciales
Ejemplo: Lectura de archivos secuenciales. Lee un archivo y muestra sus caracteres en pantalla.
Termina cuando se encuentre el fin del archivo (EOF).
FILE * pf;
char * nfile = "test.txt";
pf = fopen(nfile,"rt");
if(pf==NULL){
puts("Error abriendo archivo.");
return 1;
}else{
int c;
do{
c=fgetc(pf);
if(c=='\n')
printf("\n");
else
putchar(c);
}while(c!=EOF); //Puedes utilizar feof()!
fclose(pf);
}
Manejo de archivos secuenciales
Ejemplo: Manipulando cadenas de caracteres, funciones fputs() y fgets().
◦ fputs() escribe la cadena en el archivo asociado, devuelve EOF si no ha podido
escribirla
◦ fgets() lee una cadena del archivo, termina su lectura cuando encuentra el
carácter de fin de línea, o cuando ha leído n-1 caracteres si se especifica n en
sus argumentos.
◦ Ejemplos: Lee los primeros 10 caracteres de un archivo, y los coloca en un
segundo.
FILE * pf, *pf2;
char * nfile = "test.txt";
char * nfile2 = "test2.txt";
pf = fopen(nfile,"rt");
pf2 = fopen(nfile2,"wt");
char cadena[10];
if(pf==NULL || pf2==NULL){
puts("Error abriendo archivos.");
return 1;
}else{
fgets(cadena,10,pf);
fputs(cadena,pf2);
fclose(pf);
fclose(pf2);
}
Manejo de archivos secuenciales
Ejemplo: Manipulando variables de cualquier tipo de dato estándar usando códigos de formato (%d, %f,
etc) con los flujos asociados, fprint() y fscanf().
◦ fprintf() escribe datos en secuencia en el archivo asociado formateados según los argumentos de la
función. Retorna el número total de caracteres impresos si tuvo éxito, o un número negativo en
caso contrario.
◦ fscanf() lee datos formateados de un archivo asociado, y los almacena según el formato dado en
variables adicionales pasadas como parámetros a la función.
◦ Ejemplos:
char * nfile2 = "test2.txt";
FILE *pf2 = fopen(nfile2,"w+");
if(pf2==NULL){
puts("Error abriendo archivos.");
return 1;
}else{
fprintf(pf2,"%f %s",3.1416f,"PI");
rewind(pf2); //Coloca el indicador de posición al principio
float valorpi;
char descripcion [100];
fscanf(pf2,"%f",&valorpi);
fscanf(pf2,"%s",descripcion);
printf("Valores leidos del archivo: %f %s",valorpi,descripcion);
fclose(pf2);
}
Resumen de Prototipo de funciones
Las funciones de E/S se encuentran definidas
en la librería stdio.h.
int putc(int c, FILE * pf);
int fputc(int c, FILE * pf);
int getc(FILE * pf);
int fgetc(FILE * pf);
int fputs(char * cadena, FILE * pf);
char * gets(char * cadena, int n, FILE * pf);
int fprintf(FILE * pf, const char * formato, …);
int fscanf(FILE * pf, const char * formato, …);
int feof(FILE * pf);
Archivos binarios
En C son secuencias de 0s y 1s.
Optimizan la memoria ocupada por un
archivo:
◦ En modo texto primero se convierte el valor
numérico en una cadena de dígitos y después se
escribe en el archivo.
◦ Sin embargo, la lectura de archivos binarios se
tiene que realizar desde un entorno de un
programa en C.
C proporciona dos funciones de entrada y
salida para archivos binarios: fread() y fwrite().
Archivos binarios
fwrite(): Escribe un buffer de cualquier tipo de dato
en un archivo binario.
◦ fwrite(const void * ptr, size_t tam, size_t n, FILE *pf)
ptr: Puntero al buffer (e.g., arreglo, variable) que contiene los datos
tam: Tamaño del tipo de datos de cada elemento del buffer
n: Número de elementos a escribir
pf: Puntero al archivo
Ejemplo: Elevar una variable real al cuadrado y
guardar los resultados en un archivo binario
FILE *fd;
double x;
fd = fopen(“numeros.dat","wb");
for(x=0.5;x>0.01;){
fwrite(&x, sizeof(double), 1,fd);
x = pow(x,2.0);
}
fclose(fd);
Archivos binarios
fread(): Lee un archivo de n bloques de bytes y los
almacena en un buffer. .
◦ fread(void * ptr, size_t tam, size_t n, FILE *pf)
ptr: Puntero al buffer donde se depositarán los datos
tam: Tamaño del tipo de datos de cada elemento a leer
n: Número de elementos a leer
pf: Puntero al archivo
Ejemplo: Leer los cuadrados de los números reales
del ejemplo anterior.
FILE *fd;
double x, suma;
fd = fopen(“numeros.dat","wb");
while(!eof(fd)){
fread(&x, sizeof(double), 1,fd);
}
fclose(fd);
Ejemplo fread, fwrite
typedef struct {
char nombre[SIZEOFNAME];
int idacc;
float limite;
float balance;
float cargos;
float creditos;
} ACCOUNT;
ACCOUNT accounts[TOTALCUENTAS], acc;
//…Asume que el arreglo de cuentas ha sido
//inicializado con datos hasta TOTALCUENTAS
FILE *fw, *fr;
//Abre archivo para escritura, asume no error
fw = fopen("cuentas.dat","wb");
Ejemplo fread, fwrite
//Escribe todos los datos del arreglo al archivo
fwrite(accounts,sizeof(ACCOUNT),TOTALCUENTAS,fw);
fclose(fw);
//Ahora abre el mismo archivo para lectura de datos
fr = fopen("cuentas.dat","rb");
while(!feof(fr)){
//Lee el archivo registro por registro
if(fread(&acc,sizeof(ACCOUNT),1,fr))
printAccount(acc);
}
EJERCICIOS:
-Modifica la escritura para escribir registro por
registro
-Modifica la lectura para leer todo el bloque de
datos en una instancia
Acceso aleatorio
El acceso aleatorio a los datos de un archivo
se hace mediante su posición, es decir, el
lugar relativo que estos ocupan.
Se pueden leer y escribir registros en
cualquier orden y posición.
Se tiene que programar la relación existente
entre el contenido del registro y la posición
que ocupa.
Se utilizan las funciones fseek() y ftell().
Acceso aleatorio
fseek(): Puede tratar un archivo en C como un
array, situando el puntero de un archivo en una
posición aleatoria dependiendo de sus
argumentos.
◦ fseek(File * pf, long desplazamiento, int origen)
El desplazamiento es el número de bytes a mover con
respecto al origen.
El origen es la posición desde la que se cuenta el
número de bytes a mover. Toma tres valores:
0 : Desde el inicio del archivo (SEEK-SET)
1: Desde la posición actual del archivo (SEEK-CUR)
2: Desde el final del archivo (SEEK-END)
Retorna 0 si es exitoso el posicionamiento
Acceso Aleatorio
Ejemplo:
//Solicita el numero de registro
int regnum;
ACCOUNT acc;
cout<<“El numero de registro a visualizar:";
cin>>regnum;
//Desplazate a la posicion del registro
int result =
fseek(fr,regnum*sizeof(ACCOUNT),SEEK_SET);
if(result!=0){
cout<<"Error!"<<endl;
}else{
//Lee e imprime el registro
fread(&acc,sizeof(ACCOUNT),1,fr);
printAccount(acc);
}
Acceso aleatorio
ftell(): Obtiene la posición actual del archivo.
Devuelve la posición como el total de bytes
desde el inicio del archivo.
◦ ftell(File * pf)
Retorna -1L si un error ocurre
Ejemplo:
int result =
fseek(fr,regnum*sizeof(ACCOUNT),SEEK_SET);
long msize = ftell(fr);
cout<<"Size "<<msize<<" sizeof account
"<<sizeof(ACCOUNT)<<endl;