Archivos de números • Para leer datos desde un archivo de texto como enteros (o números en general) se puede utilizar fscanf. Tema 10c • Para escribir datos numéricos en archivos de texto se puede utilizar fprintf. • Los archivos deben ser abiertos en modo texto. • Se utilizan las conversiones %d y %f ya vistas. Manejo de archivos de datos en C Archivos de números Archivos de números #include < stdio.h> • Ejemplo: Archivo de texto con números en un formato fijo int main(){ FILE* archivo; archivo = fopen("test3.txt","r"); if(archivo!=NULL){ int ds[4],i; double fs[4]; fscanf(archivo,"%d %d %d %d\ n", &ds[0],&ds[1],&ds[2],&ds[3]); fscanf(archivo,"%d, %d, %d, %d\ n", &ds[0],&ds[1],&ds[2],&ds[3]); fscanf(archivo,"%lf ; %lf ; %lf ; %lf \n" &fs[0],&fs[1],&fs[2],&fs[3]); fclose(archivo); } } 1 2 3 4 7, 8, 9, 10 1.4 ; 0.7 ; 9.001 ; 67.0 Archivos mixtos Archivos mixtos #include <stdio.h > • Archivos de texto con datos alfanuméricos • Basta con especificar el tipo de conversión deseada para cada tipo de dato. colo-colo 0 huachipato 3 everton 5 cobreloa 1 u.Catolica 2 wanderers 3 int main(){ FILE* archivo ; archivo = fopen("test4.txt","r"); if(archivo !=NULL){ char visita[32], local[32]; int gvisita , glocal; int r=4; while(1){ r=fscanf(archivo,"%s %d %s % d\n", local,&glocal,visita,&gvisita); if(r !=4) break; if(glocal>gvisita) printf("Gana local (%s)\n",local); else if(glocal<gvisita) printf("Gana visita (%s)\n",visita ); else printf("Empate\n"); } fclose(archivo); } return 1; } 1 Archivos binarios • Deben ser abiertos en modo binario. • La información se guarda en formato binario. • Si se abre el archivo con un editor de texto, aparece basura. • Se pueden intercalar distintos tipos de datos Archivos binarios • fread – Lee datos binarios desde un archivo – size_t fread( unsigned int, Número de bytes leídos void* buffer, size_t num_bytes , size_t cuenta, FILE* fp); Variable donde dejar la información leída Tamaño del tipo de dato Numero de elementos A leer Flujo desde donde leer Archivos binarios Archivos binarios • sizeof • fwrite – Escribe datos binarios a un archivo – size_t fwrite( unsigned int, Número de bytes escritos void* buffer, size_t num_bytes , size_t cuenta, FILE* fp); Variable desde donde tomar la información Tamaño del tipo de dato Numero de elementos A escribir – Entrega en numero de bytes que ocupa un tipo de dato – Es un operador calculado en tiempo de compilación. sizeof(int) à4 int i; sizeof(i) à 4 Flujo donde se debe escribir Archivos binarios void escribir(FILE* archivo) { archivo = fopen("test5.dat","w+b"); if(archivo !=NULL){ int i,k ; k=1; for(i=0;i<10;i++){ size_t ws; ws = fwrite(&k,sizeof(k),1,archivo); k=k*2; printf("%d enteros escritos en %d bytes\ n", ws, ws *sizeof(int) ); } fclose(archivo); } } Archivos binarios void leer(FILE* archivo){ archivo = fopen("test5.dat","r+b"); if(archivo !=NULL){ int i,k; while(fread(&k,sizeof(int),1,archivo)==1){ printf("%d \n",k); } fclose(archivo); } } 2 Archivos binarios int main(int argc, char* argv[]){ FILE* archivo; printf("%s",argv[1]); if(argc>1 && strcmp(argv[1],"w")==0) escribir(archivo); else leer(archivo); Archivos binarios • Así como se puede leer y escribir datos simples, también se pueden leer y escribir datos estructurados. • El esquema es el mismo, basta con especificar el tamaño correcto. return 1; } Archivos binarios struct pokemon{ char nombre[12]; int tipo; //0: fuego, 1:planta, //2:agua, 3:electrico double fuerza; double energia; }; Archivos binarios void escribir(FILE* archivo){ archivo = fopen("test6.dat","w+b"); if(archivo!=NULL){ int i,k; size_t wb; struct pokemon pk[3]; strcpy(pk[0].nombre,"pikachu"); pk[0].tipo=3; pk[0].fuerza=120; pk[0].energia=87; wb = fwrite(pk,sizeof(struct pokemon),3,archivo); printf("%d bytes escritos en %d elementos\n", wb*sizeof(struct pokemon), wb); fclose(archivo); Archivos binarios void escribir(FILE* archivo){ archivo = fopen("test6.dat","w+b"); if(archivo!=NULL){ int i,k; struct pokemon pk1, pk2, pk3; strcpy(pk1.nombre,"pikachu"); pk1.tipo=3; pk1.fuerza=120; pk1.energia=87; … fwrite(&pk1,sizeof(struct pokemon),1,archivo); fwrite(&pk2,sizeof(struct pokemon),1,archivo); fwrite(&pk3,sizeof(struct pokemon),1,archivo); fclose(archivo); } } Archivos binarios void leer(FILE* archivo){ printf("Leyendo\n"); archivo = fopen("test6.dat","r+b"); if(archivo!=NULL){ int i; struct pokemon pk; while(fread(&pk,sizeof(struct pokemon),1,archivo)==1){ printf("%s\n",pk.nombre); } fclose(archivo); } } } 3 Archivos binarios • En archivos binarios ya no es necesario realizar accesos secuenciales. • Es muy natural realizar accesos a estructuras de datos especificas, tanto para lectura como para escritura. Archivos binarios • fseek – Mueve el cursor de lectura escritura a una posición especifica del archivo – int fseek(FILE* f, long nbytes, int origen); Cero en caso de éxito, distinto de cero en error Numero de bytes a mover el cursor Desde donde contar nbytes Descriptor de archivo Archivos binarios • fseek Archivos binarios • ftell – Origen: • SEEK_SET : Principio del archivo • SEEK_CUR: Posición actual • SEEK_END: Fin del archivo – Indica la posición actual en el archivo (bytes respecto al inicio) – long int ftell(FILE* f); Posición del archivo, -1 en caso de error. Archivos binarios void leern (FILE* archivo, int n ){ printf("Leyendo %d \n",n) ; archivo = fopen("test6.dat","r+b"); if(archivo!=NULL){ int i ; struct pokemon pk ; fseek(archivo, n* sizeof(struct pokemon),SEEK_SET ); fread(&pk,sizeof(struct pokemon),1,archivo); printf("%s\ n",pk.nombre ); fclose(archivo ); } } Descriptor de archivo Archivos binarios void leerrev(FILE* archivo){ archivo = fopen("test6.dat","r+b"); if(archivo!=NULL){ int i; struct pokemon pk; fseek(archivo,-1*sizeof(struct pokemon),SEEK_END); while(fread(&pk,sizeof(struct pokemon),1,archivo)==1){ printf("%s\n",pk.nombre); fseek(archivo,-2*sizeof(struct pokemon),SEEK_CUR); } fclose(archivo); } } 4 Fin Tema 10c Manejo de archivos de datos en C 5