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;