===== Archivos ===== Todas la funciones de acceso a archivos requieren incluir: #include Para operar con archivos se requiere declarar un puntero a un descriptor de archivo: FILE *in, *out; /* file pointer */ Antes de leer o escribir hay que abrir el archivo. La excepción corresponde a la entrada estándar, salida estándar y salida estándar de errores que ya están abiertos. in= fopen(nombre, "r"); /* "r" por read */ out= fopen(nombre, "w"); /* "w" por write o "a" por append */ /* fopen retorna NULL en caso de error */ Después de leer o escribir se debe cerrar el archivo para liberar recursos y para asegurar que se escriba todo el contenido de un archivo de salida. De lo contrario, algunos bytes podrían permanecer en buffers internos. fclose(out); Leer/escribir de a un caracter: c= getc(in); putc(c, out); Devolver un caracter leído, para que se vuelva a leer. ungetc(c, in); Entrada/salida con formato: fprintf(fp, formato, ...); fscanf(fp, formato, ...); Lectura/escritura de bloques de bytes: char buf[80]; size_t leidos= fread(buf, 1, 80, in); size_t escritos= fwrite(buf, 1, 80, out); Determinar si se llegó al final del archivo: if (feof(in)) ... Determinar si ocurrió algún error de lectura/escritura: if (ferror(out)) ... Acceso directo: fseek(in, pos, SEEKSET); Posiciona el archivo de tal forma que el próximo caracter que se leerá de in es el que encuentra en el desplazamiento pos, medido desde el comienzo del archivo. ==== Entrada estándar, salida estándar y salida estándar de errores ==== Todo proceso al partir cuenta con los siguientes descriptores de archivos para leer la entrada estándar, escribir la salida estándar o escribir en la salida estándar de errores respectivamente: FILE *stdin, *stdout, *stderr; No es necesario abrir estos archivos porque se abren automáticamente al iniciarse el proceso. Además todos los archivos abiertos por un proceso se cierran automáticamente al terminar ese proceso. Es usual usar getchar y putchar para leer/escribir de la entrada/salida estándar. Pero estas son en realidad macros que recurren a getc/putc: #define getchar() getc(stdin) #define putchar(c) putc((c), stdout) Es decir una invocación a getchar() se substituye textualmente por getc(stdin). ==== Ejemplo: copia de archivos ==== El siguiente programa copia un archivo: #include #include void filecopy(FILE *in, FILE *out) { char buf[1024]; size_t size; while ((size= fread(buf, 1, 1024, in))!=0) { if (fwrite(buf, 1, size, out)!=size) { perror("fwrite"); exit(1); } } if (ferror(in)) { perror("fread"); exit(1); } } int main(int argc, char *argv[]) { FILE *in, *out; if(argc!=3) { fprintf(stderr, "uso: %s \n", argv[0]); exit(1); } else { if ((in= fopen(argv[1], "r"))==NULL) { perror(argv[1]); exit(1); } if ((out= fopen(argv[2], "w"))==NULL) { perror(argv[2]); exit(1); } filecopy(in, out); fclose(in); fclose(out); } return 0; } ==== Ejercicio ==== Estudie la [[http://users.dcc.uchile.cl/~lmateu/CC3301/download/filesort.zip|solución]] de la [[http://users.dcc.uchile.cl/~lmateu/CC3301/tareas/t2-2015-1.pdf|tarea 2 de 2015/1]]. Use el mismo enfoque de esa solución para resolver la pregunta 1 del [[http://users.dcc.uchile.cl/~lmateu/CC3301/controles/c2-151.pdf|control 2 de 2015/1]]. Pruebe su solución con el archivo [[http://users.dcc.uchile.cl/~lmateu/CC3301/download/buscar.zip|buscar.zip]]. Siga las instrucciones que se indican en el archivo Makefile. Este ejercicio combina el uso de punteros a funciones con acceso directo a archivos por medio de fseek.