Entrada/Salida Programación en C ENTRADA/SALIDA Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles Entrada/Salida UPCO ICAI Departamento de Electrónica y Automática 1 Programación en C Relación Programa - Sistema Operativo - Hardware • • • Mi función que quiere Mi programa no maneja hacer una operación directamente el de salida por pantalla hardware ImpResultados() El sistema operativo es el que maneja el Biblioteca printf() hardware (a través de PROGRAMA driver) Llamada al SO El compilador incorpora unas SISTEMA Driver bibliotecas de OPERATIVO funciones que saben hablar con el Sistema Operativo (Llamada al HARDWARE sistema operativo) para que éste hable con el Disco hardware Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 2 Entrada/Salida Programación en C Sistema Operativo • • Primer programa que ejecuta la CPU del ordenador – Operación de carga del sistema operativo Presentar al usuario del ordenador una máquina virtual que sea más fácil de utilizar y programar que el hardware subyacente – La estructura a nivel de hardware es difícil de programar: • Programación de la tarjeta de video • Programación del chip controlador del disco duro – El SO presenta una visión sencilla del hardware • Directorios, archivos • – A través de llamadas al SO se puede trabajar con la máquina virtual Otras tareas: – Administrar los recursos de la máquina • Repartir el tiempo de CPU entre diferentes tareas Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 3 Entrada/Salida Programación en C Ejemplo de complejidad: Disco duro Visto desde el hardware Pista Sector Memoria Procesador Controlador de disco Disco Cilindro Cabeza Disco Visto desde el sistema operativo Directorio raiz (D:) MiDirectorio CompiladorC MiPrograma.exe Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 4 Entrada/Salida Programación en C Relación en alto nivel: Buffer de caracteres (ASCII) Visto desde el Sistema Operativo: ARCHIVO o FICHERO Vector en memoria manejado por las funciones de entrada/salida Visto desde C: BUFFER Fichero Hola mundo Carácter de control Disco Buffer H Hola mundo o l \n m Carácter normal Puntero inicial del buffer Teclado y pantalla funcionan como un archivo: stdin y stdout Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles a u n d o \n EOF Indica final de fichero = Inicio del fichero Cada vez que se lee o escribe en el buffer avanza el puntero UPCO ICAI Departamento de Electrónica y Automática 5 Entrada/Salida Programación en C Entrada/salida en alto nivel • • Toda la entrada y la salida se realiza a través de ficheros 1. Abrir el fichero (fopen) – – – – • • Nombre del fichero y modo de trabajo (lectura o escritura) Se establece la conexión a través del SO con el fichero Se crea el buffer: vector que actúa como almacenamiento intermedio. Se devuelve un identificado (puntero) para que el programa pueda manejar varios ficheros 2. Escribir o leer en el fichero (fprintf, fscanf, fgets,fputs) – Se envía o extrae información del buffer – Mediante los identificadores se manejan diferentes buffers – En cada operación avanza el puntero en el buffer 3. Cerrar el fichero – Liberar el buffer y al SO de controlar el fichero • stdin y stdout no hay que abrirlos ni cerrarlos Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 6 Entrada/Salida Programación en C Ejemplo de entrada/salida #include <stdio.h> main () { char s[200]; FILE *pfic; pfic=fopen("quijote.txt","r"); if (pfic==NULL) return 0; while(fgets(s,200-1,pfic)!=NULL) fprintf(stdout,"%s",s); while(fscanf(pfic,"%199s",s)!=EOF) printf("%s\n",s); fclose(pfic); pfic=fopen("quijote.txt","r"); if (pfic==NULL) return 0; while(fscanf(pfic,"%199s",s)!=EOF) printf("%s\n",s); fclose(pfic); return 0; Hola esto es una prueba de numeros 2, 3, 4 5a 4ff f4Hola esto es una prueba de numeros 2, 3, 4 5a 4ff f4 } Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 7 Entrada/Salida Programación en C Ejemplo de entrada/salida Fichero donde están los prototipos de la funciones de entrada/salida #include <stdio.h> main () { char s[200]; FILE *pfic; Puntero a la estructura de control del buffer del fichero: sólo sirve de identificador pfic=fopen("quijote.txt","r"); Abrir el fichero en modo lectura if (pfic==NULL) Comprobación de que se ha abierto correctamente return 0; while(fgets(s,200-1,pfic)!=NULL) fprintf(stdout,"%s",s); while(fscanf(pfic,"%199s",s)!=EOF) printf("%s\n",s); fclose(pfic); Cerrar fichero pfic=fopen("quijote.txt","r"); if (pfic==NULL) return 0; while(fscanf(pfic,"%199s",s)!=EOF) printf("%s\n",s); fclose(pfic); return 0; } Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles Lectura línea a línea del fichero Lectura secuencias de caracteres separadas por blancos o \n. No hace hace nada porque el puntero ya está al final del buffer Aquí si se realiza la lectura porque se ha vuelto a abrir el fichero: el puntero de control de la lectura en el buffer se vuelve a situar al principio UPCO ICAI Departamento de Electrónica y Automática 8 Entrada/Salida Programación en C Buffer del ejemplo Al abrir el fichero (fopen) , se crea este buffer y se sitúa el puntero al principio H o u l e 3 a b , e a s \n d 4 \n t o e 5 e n a fscanf u 4 s m f e f El buffer se destruye al cerrar el fichero (fclose) Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles u r n o f a s 4 p 2 r , EOF No hay \n al final de este fichero UPCO ICAI Departamento de Electrónica y Automática 9 Entrada/Salida Programación en C Ejemplo de escritura (I) #include <stdio.h> main () { char sFuente[20]; char sDest[20]; FILE *pficFuente; FILE *pficDest; int i; printf("Nombre del fichero a copiar: "); fscanf(stdin,"%19s",sFuente); printf("Nombre del fichero destino: "); fscanf(stdin,"%19s",sDest); if ((pficFuente=fopen(sFuente,"r"))==NULL) { printf("ERROR: Fichero %s no existe o es incorrecto\n",sFuente); return 0; } Escritura if ((pficDest=fopen(sDest,"w"))==NULL) { printf("ERROR: Fichero %s no existe o es incorrecto\n",sDest); fclose(pficFuente); return 0; } Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 10 Entrada/Salida Programación en C Ejemplo de escritura (II) La operación se realiza carácter a carácter while ((i=fgetc(pficFuente))!=EOF) { if(fputc(i,pficDest)==EOF) { printf("ERROR: Fichero %s tiene problemas\n",sDest); fclose(pficFuente); return 0; } fputc(i,stdout); } fclose(pficDest); fclose(pficFuente); return 0; } Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles Entrada/Salida Ejemplo de escritura (III) • Con fgets y fputs UPCO ICAI Departamento de Electrónica y Automática 11 Programación en C Se lee la línea completa incluido el \n y se le añade \0 al final while (fgets(s,MAXLINEA,pficFuente)!=NULL) { if(fputs(s,pficDest)==EOF) { printf("ERROR: Fichero %s tiene problemas\n",sDest); fclose(pficFuente); return 0; } } fclose(pficDest); fclose(pficFuente); return 0; Se escribe la cadena de caracteres completa con excepción del \0 } Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 12 Entrada/Salida Programación en C Peligro al mezclar fscanf con fgetc o fgets • Ejemplo que no espera #include <stdio.h> Escriba algo: Hola Pulse enter Adios main() { char s[100]; fprintf(stdout,"Escriba algo: "); fscanf(stdin,"%99s",s); Parace que no ejecuta fgetc fprintf(stdout,"Pulse enter "); fgetc(stdin); fprintf(stdout,"Adios”); return 0; } • ¿Qué ocurre? – fscanf sólo lee Hola sin el \n del final: el puntero del buffer apunta a \n: el buffer no queda vacío – fgetc lee un carácter del buffer: \n y devuelve el control Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 13 Entrada/Salida Programación en C Entrada/Salida interactiva • stdin: – Cualquier función que lea de la stdin no devuelve el control hasta que no se pulse enter. El \n correspondiente siempre aparece al final. – No mezclar fscanf con fgets y fgetc • fscanf: sólo lee campos delimitados por \n, blancos y tabulador (no incl) • fgets: lee hasta encontrar el \n incluido éste (suficiente tamaño) • fgetc: lee un carácter del buffer, si no lo hay espera • stdout: • – Dependiendo del sistema, hasta que no se escriba \n en el buffer no aparece nada en la stdout Los buffers se guardan en memoria – El archivo correspondiente (de verdad, pantalla, etc) puede ser que no se actualice hasta que no se cierre. – Si hay un corte de luz, la información puede perderse porque no ha sido actualizada en el archivo físico Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 14 Entrada/Salida Programación en C Errores comunes en la entrada/salida • • Olvidar cerrar el fichero – Conforme se van abriendo ficheros y no se cierran, se agota la memoria disponible en el ordenador Creer que el puntero que devuelve fopen es el puntero que controla la posición actual dentro del buffer – fopen devuelve sólo un puntero a la estructura de control creada para controlar el buffer correspondiente al fichero – No se debe modificar porque se perdería la conexión con el fichero – El puntero que controla la posición actual de lectura o escritura dentro del buffer es inaccesible al usuario • • Sólo fscanf o fprintf o similar saben como manejar ese puntero a través del puntero que identifica al fichero (el devuelto por fopen()) Creer que el puntero que devuelve fopen es el fichero físico – Por economía de palabras nos referimos a ese puntero como si fuera nuestro fichero: es sólo la clave para acceder al fichero Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 15 Entrada/Salida Programación en C Fichero ASCII y fichero binario • Sólo se ha trabajado con ficheros ASCII – Secuencia de bytes interpretados según la tabla ASCII (entrada/salida con formato) 1 2 3 \n 31 32 33 0a Contenido del buffer interpretado Contenido del buffer tal cual Valores en hexadecimal • Ficheros binario – La secuencia de bytes no está pensada para ser interpretada según la tabla ASCII – Se leen o escriben bytes o ristras de bytes Prof. José A. Rodríguez Mondéjar Prof. Álvaro Sánchez Miralles UPCO ICAI Departamento de Electrónica y Automática 16
Puede agregar este documento a su colección de estudio (s)
Iniciar sesión Disponible sólo para usuarios autorizadosPuede agregar este documento a su lista guardada
Iniciar sesión Disponible sólo para usuarios autorizados(Para quejas, use otra forma )