Transcript Archivos

Archivos
Programación
Introducción
•El manejo de archivos no está ínter construido en C
•Se provee en la biblioteca stdio.h con funciones que inician con "f"
•Las funciones trabajan igual que las de entrada y salida estándar
•Los archivos se representan como secuencias de caracteres
•Es fácil moverse hacia adelante para leer o escribir caracteres, pero es casi
imposible moverse hacia atrás
Flujos
•Antes de leer o escribir se debe asociar un flujo (stream) a los archivos
•El flujo es una apuntador a una estructura
•Todo programa en C abre tres flujos: stdin, stdout, stderr
•stdin: entrada estándar esta relacionada con el teclado
•stdout: salida estándar esta relacionada con la pantalla
•stderr: salida estándar de errores esta relacionada con la pantalla
Que es un Flujo?
•Un flujo crea una región de memoria (buffer) entre el programa y el archivo en
disco
•Esto reduce los accesos a disco
•Los caracteres se leen en bloques en el buffer, o se escriben en bloques en el
disco
Flujo de salida
a b c d e f
a b c d e f
Flujo de entrada
Porque stdout y stderr?
Por la redirección soportada en Unix, DOS, OS/2, etc.
#include <stdio.h>
int main(){
printf("Escritura a stdout\n");
fprintf(stderr,"Escritura a stderr\n");
return 0;
}
c:> prog
Escritura a stdout
Escritura a stderr
c:> prog > archivo.txt
Escritura a stderr
c:> type archivo.txt
Escritura a stdout
stdin está basado en líneas
los caracteres tecleados son retenidos (buffered) hasta presionar
ENTER
Se declara int aunque
#include <stdio.h>
se leerán caracteres
abc
int main(){
lee 'a'
int ch;
lee 'b'
while((ch=getchar())!= EOF)
lee 'c'
printf("lee '%c''n",ch);
lee '
printf("EOF\n");
'
return 0;
d
}
lee 'd'
lee '
'
^Z
EOF
Operaciones básicas con archivos
Abrir archivo - fopen(archivo)
Leer de o escribir en archivo
fscanf(archivo,formato,lista) - lee diferentes variables
fgetc(archivo) - lee un carácter
fgets(cadena,tamaño,archivo) - lee una cadena
fprintf(archivo,formato,lista) - escribe diferentes variables
fputc(archivo) - escribe un carácter
fputs(cadena,archivo) - escribe una cadena
Cerrar archivo - fclose(archivo)
Lectura de un archivo
#include <stdio.h>
#include <conio.h>
int main(){
char nombre[80];
FILE *entrada;
int ch;
printf("Archivo: ");
scanf("%79s",nombre);
if((entrada=fopen(nombre,"r"))==NULL){
fprintf(stderr,"fallo la lectura de %s",entrada);
perror("debido a");
getch();
return 1;
}
while((ch=fgetc(entrada))!= EOF)
putchar(ch);
fclose(entrada);
getch();
return 0;
}
Ejemplos
El siguiente programa lee caracteres desde el teclado y los escribe en un
archivo carácter por carácter hasta que el usuario teclea ENTER:
#include <stdio.h>
#include <conio.h>
main(){
char p;
FILE *archivo;
archivo = fopen("test1.txt","w");
if(archivo!=NULL){
while((p=getchar())!='\n')
fputc(p,archivo);
fclose(archivo);
}
else
printf("No se puede crear el archivo...");
getch();
}
Lee un archivo hasta el final y lo despliega en pantalla
#include <stdio.h>
#include <conio.h>
main(){
char p;
FILE *archivo;
archivo = fopen("test1.txt","r");
if(archivo!=NULL){
while(!feof(archivo)){
p = fgetc(archivo);
putchar(p);
}
fclose(archivo);
}
else
printf("No se puede abrir el archivo...");
getch();
}
Lee cadenas desde el teclado y las escribe en un archivo usando fputs:
#include <stdio.h>
#include <conio.h>
main(){
char cadena[30];
FILE *archivo;
archivo = fopen("test2.txt","w");
if(archivo!=NULL){
do{
printf("Escriba una cadena: ");
gets(cadena);
if(cadena[0]!='\0')
fputs(cadena,archivo);
}while(cadena[0]!='\0');
fclose(archivo);
}
else
printf("No se puede crear el archivo...");
getch();
}
Lee cadenas de 30 caracteres desde un archivo usando fgets y las despliega
en pantalla.
#include <stdio.h>
#include <conio.h>
main(){
char cadena[30];
FILE *archivo;
archivo = fopen("test2.txt","r");
if(archivo!=NULL){
while(!feof(archivo)){
fgets(cadena,30,archivo);
puts(cadena);
}
fclose(archivo);
}
else
printf("No se puede leer el archivo...");
getch();
}
Escritura de datos numéricos con fprintf
#include <stdio.h>
#include <conio.h>
main(){
int i;
FILE *archivo;
archivo = fopen("test4.txt","w");
if(archivo!=NULL){
for(i = 0; i< 10; i++)
fprintf(archivo,"%d %d\n",i,i*i);
fclose(archivo);
}
else
printf("No se puede crear el archivo...");
getch();
}
Lectura de datos numéricos
#include <stdio.h>
#include <conio.h>
main(){
int i,j;
FILE *archivo;
archivo = fopen("test4.txt","r");
if(archivo!=NULL){
for(i = 0; i< 10; i++){
fscanf(archivo,"%d %d\n",&i,&j);
printf("%d %d\n",i,j);
}
fclose(archivo);
}
else
printf("No se puede crear el archivo...");
getch();
}
Escritura de datos numéricos con fprintf
#include <stdio.h>
#include <conio.h>
main(){
int i;
FILE *archivo;
archivo = fopen("test4.txt","w");
if(archivo!=NULL){
for(i = 0; i< 10; i++)
fprintf(archivo,"%d %d\n",i,i*i);
fclose(archivo);
}
else
printf("No se puede crear el archivo...");
getch();
}
Lectura de datos numéricos
#include <stdio.h>
#include <conio.h>
main(){
int i,j;
FILE *archivo;
archivo = fopen("test4.txt","r");
if(archivo!=NULL){
for(i = 0; i< 10; i++){
fscanf(archivo,"%d %d\n",&i,&j);
printf("%d %d\n",i,j);
}
fclose(archivo);
}
else
printf("No se puede crear el archivo...");
getch();
}
Quiz
Escriba un programa que escriba en un archivo de nombre “datos.txt” su
nombre, direccion, telefono y la carrera que está cursando. Cada elemento
escríbalo en una línea distinta.
Abrir archivo - fopen(archivo,modo)
Leer de o escribir en archivo
fscanf(archivo,formato,lista) - lee diferentes variables
fgetc(archivo) - lee un carácter
fgets(cadena,tamaño,archivo) - lee una cadena
fprintf(archivo,formato,lista) - escribe diferentes variables
fputc(archivo) - escribe un carácter
fputs(cadena,archivo) - escribe una cadena
Cerrar archivo - fclose(archivo)
Ejemplo de calificaciones
#include <stdio.h>
#include <conio.h>
Escribe las calificaciones de un
grupo de alumnos
void escribeCalificaciones(FILE *archivo){
int i,j,n,matricula;
float calificacion;
printf("Ingrese numero de alumnos: ");
scanf("%d",&n);
fprintf(archivo,"%d",n);
for(i=0;i<n;i++){
printf("Ingrese la matricula del alumno: ");
scanf("%d",&matricula);
fprintf(archivo,"\n%d ",matricula);
for(j=0;j<5;j++){
printf("Ingrese la calificacion %d: ",j);
main(){
scanf("%f",&calificacion);
FILE *archivo;
fprintf(archivo,"%.2f ",calificacion);
if((archivo = fopen(
}
}
"datosAlumnos.txt",
fclose(archivo);
"w"))!=NULL)
}
escribeCalificaciones(archivo);
else
printf("No se pudo crear el
archivo.");
}
#include <stdio.h>
#include <conio.h>
Lee las calificaciones de
un grupo de alumnos y
calcula el promedio final.
void leerCalificaciones(FILE *archivo){
int i,j,n,matricula;
float calificacion,suma;
fscanf(archivo,"%d",&n);
printf("Numero de alumnos: %d\n",n);
printf("clave \t1\t2\t3\t4\t5\tprom.\n");
for(i=0;i<n;i++){
fscanf(archivo,"%d",&matricula);
printf("%d",matricula);
suma = 0;
main(){
for(j=0;j<5;j++){
FILE *archivo;
fscanf(archivo,"%f",&calificacion);if((archivo = fopen(
printf("\t%.2f ",calificacion);
"datosAlumnos.txt","r"))!=NU
LL)
suma += calificacion;
leerCalificaciones(archivo);
}
else
printf("\t%.2f\n",suma/5.0);
printf("No se pudo leer el
}
archivo.");
fclose(archivo);
getch();
}
}
Leer datos de los clientes
de un banco.
void leerClientes(FILE *archivo){
int cuenta;
char nombre[30];
float saldo;
while(!feof(archivo)){
fscanf(archivo,"%d\n",&cuenta);
fscanf(archivo,"%s\n",nombre);
fscanf(archivo,"%f\n",&saldo);
printf("%d, %s, saldo = %.2f\n",cuenta,nombre,saldo);
}
fclose(archivo);
}
main(){
FILE *archivo;
if((archivo = fopen("cuentas.txt","r"))!=NULL)
leerClientes(archivo);
else
printf("No se pudo leer el archivo.");
getch();
}
Actividad
1. Escriba una función que despliegue todos los clientes de un banco que
tienen saldos negativos.
2. Escriba una función que despliegue todos los clientes de un banco que
tienen saldos entre 1,000 y 1,000,000.
3. Escriba una función que despliegue todos los clientes de un banco que
escriba en otro archivo los datos de los clientes que tienen saldos negativos.
Escritura al final de archivos
Al abrir un archivo con fopen se pueden especificar los siguientes modos:
“r” – abrir para solo lectura. El archivo debe existir.
“w” – abrir solo para escritura si existe el archivo, se borra.
“a” – abrir para agregar nuevos datos al final.
“r+” – abrir para realizar modificaciones, es decir, leer o escribir. El archivo
debe existir.
“w+” – abrir para leer y escribir. Si el archivo existe lo borra.
“a+” – abrir para leer e incorporar nuevos datos al final. Si el archivo no
existe, lo crea.
ejemplo
#include <stdio.h>
#include <conio.h>
main(){
FILE *archivo;
archivo = fopen("testApend.txt","w");
fprintf(archivo,"Esta es una prueba de append\n");
fclose(archivo);
archivo = fopen("testApend.txt","a");
fprintf(archivo,"Esta linea se agrego despues.\n");
fclose(archivo);
archivo = fopen("testApend.txt","a+");
while(!feof(archivo))
putchar(fgetc(archivo));
getch();
fprintf(archivo,"Esta linea se agrego al final.\n");
fclose(archivo);
}
Un ejemplo con menú
La internase de menú permite controlar adecuadamente programas basados
en consola.
Un menú ofrece una serie de opciones para seleccionar al usuario.
El usuario elige una opción y el programa responde ejecutando la función de
la opción seleccionada.
Menú:
1. Opción uno
2. Opción dos
N. salir
Desplegar menú
void clear(){
int i;
for(i=0;i<25;i++)
printf("\n");
}
void despliegaMenu(){
clear();
printf("1. Capturar temperaturas\n\n");
printf("2. Ver temperaturas\n\n");
printf("3. Estadisticas\n\n");
printf("4. Terminar\n\n");
printf("Opcion: ");
}
leerTemperaturas
void leerTemperaturas(){
int dia,mes,anyo;
float tMax,tMin;
FILE *archivo;
clear();
printf("Introduzca fecha (dd mm aa): ");
scanf("%d %d %d",&dia,&mes,&anyo);
printf("Introduzca temperatura maxima: ");
scanf("%f",&tMax);
printf("Introduzca temperatura minima: ");
scanf("%f",&tMin);
archivo = fopen("temps.txt","a+");
fprintf(archivo,"%d %d %d %.2f %.2f\n",
dia,mes,anyo,tMax,tMin);
fclose(archivo);
}º
verTemperaturas
void verTemperaturas(){
int dia,mes,anyo,lineas=0;
float tMax,tMin;
FILE *archivo;
archivo = fopen("temps.txt","r");
clear();
do{
fscanf(archivo,"%d %d %d %f %f\n",&dia,&mes,&anyo,&tMax,&tMin);
if(tMax<60)
printf("Fecha %2d/%2d/%4d: Temp. max %.2f, Temp. min %.2f\n",
dia,mes,anyo,tMax,tMin);
if(lineas==20){
lineas = 0;
printf("Presione una tecla...");
getch();
clear();
}
else
lineas++;
}while(!feof(archivo));
printf("Presione una tecla...");
getch();
fclose(archivo);
}
estadisticas
void estadisticas(){
int dia,mes,anyo,lineas=0;
float tMax,tMin,maxima=-100,minima=100,promedio = 0;
FILE *archivo;
archivo = fopen("temps.txt","r");
clear();
do{
fscanf(archivo,"%d %d %d %f %f\n",
&dia,&mes,&anyo,&tMax,&tMin);
if(tMax<60){
if(tMax>maxima) maxima = tMax;
if(tMin<minima) minima = tMin;
promedio += tMax+tMin;
}
lineas++;
}while(!feof(archivo));
printf("Temp. max: %.2f\nTemp. min: %.2f\n"
"Promedio: %.2f\n\n\n",maxima,minima,promedio/lineas);
printf("Presione una tecla...");
getch();
fclose(archivo);
}
El menú
void menu(){
char ch;
do{
despliegaMenu();
ch = getchar();
switch(ch){
case '1':leerTemperaturas();break;
case '2':verTemperaturas();break;
case '3':estadisticas();break;
}
}while(ch!='4');
}
Inicio y función main
void inicia(){
FILE *archivo;
archivo = fopen("temps.txt","r");
if(archivo==NULL){
archivo = fopen("temps.txt","w");
fclose(archivo);
}
}
main(){
inicia();
menu();
}
Archivos de tipo aleatorio
Los archivos de tipo texto solo pueden actualizarse reescribiendo todas las
líneas de texto.
Los archivos de acceso aleatorio permiten escribir registros arbitrarios sin
necesidad de reescribirlo por completo.
Los registros en los archivos aleatorios son todos del mismo tamaño.
Se utiliza las siguietes funciones
fwrite(arreglo, tamaño, #de registros, archivo)- escribe un
arreglo de registros en un archivo.
fread(arreglo, tamaño, #de registros, archivo)- lee un arreglo
de registros de un archivo.
Ejemplo
struct alumno{
int matricula;
char nombre[20];
int carrera;
float promedio;
};
main(){
FILE *archivo;
if((archivo=fopen("alu.dat","w"))!=NULL)
escribeArchivo(archivo);
else
printf("\nel archivo no se puede crea...");
fclose(archivo);
}
void escribeArchivo(FILE *archivo){
alumno alu;
int i=0,r;
printf("Deseas ingresar informacion sobre alumnos?
(Si=1, No=0): ");
scanf("%d",&r);
while(r){
i++;
printf("Matricula: ");
scanf("%d",&alu.matricula);
fflush(stdin);
printf("Nombre: ");
gets(alu.nombre);
printf("Carrera: ");
scanf("%d",&alu.carrera);
printf("Promedio: ");
scanf("%f",&alu.promedio);
//escribe en el archivo
fwrite(&alu,sizeof(alumno),1,archivo);
printf("Deseas ingresar informacion sobre mas alumnos?
(Si=1, No=0): ");
scanf("%d",&r);
}
}
Leer archivo de datos
void leerArchivo(FILE *archivo){
alumno alu;
fread(&alu,sizeof(alumno),1,archivo);
while(!feof(archivo)){
printf("Matricula: %d\n",alu.matricula);
printf("Nombre: ");
puts(alu.nombre);
printf("Carrera: %d\n",alu.carrera);
printf("Promedio: %.2f\n",alu.promedio);
fread(&alu,sizeof(alumno),1,archivo);
}
}
main(){
FILE *archivo;
if((archivo=fopen("alu.dat","r"))!=NULL)
leerArchivo(archivo);
else
printf("\nel archivo no se puede leer...");
fclose(archivo);
getch();
}
Ejemplo con menú
void despliegaAlumno(alumno alu){
printf("\nMatricula: %d\n",alu.matricula);
printf("Nombre: ");
puts(alu.nombre);
printf("Carrera: %d\n",alu.carrera);
printf("Promedio: %.2f\n",alu.promedio);
}
long int filesize(FILE *archivo){
long int size_of_file;
fseek(archivo,0L,SEEK_END);
size_of_file = ftell(archivo);
fseek(archivo,0L,SEEK_SET);
return size_of_file;
}
void explorarArchivo(FILE *archivo){
alumno alu;
char ch;
int registro=0,maxRegistros;
//obtiene el # de registros
maxRegistros = filesize(archivo)/sizeof(alumno);
fread(&alu,sizeof(alumno),1,archivo);
despliegaAlumno(alu);
printf("\nregistro #%d, s - siguiente, a - anterior, q - salir: ",registro);
do{
ch = getch();
if(ch == 'a'&&registro>0){
registro--;
fseek(archivo,registro*sizeof(alumno),0);
fread(&alu,sizeof(alumno),1,archivo);
despliegaAlumno(alu);
printf("\nregistro #%d, s - siguiente, a - anterior, q - salir: ",registro);
}
if((ch == 's')&& registro<maxRegistros-1){
registro++;
fseek(archivo,registro*sizeof(alumno),SEEK_SET);
fread(&alu,sizeof(alumno),1,archivo);
despliegaAlumno(alu);
printf("\nregistro #%d, s - siguiente, a - anterior, q - salir: ",registro);
}
}while(ch!='q');
}