Entrada/Salida

Anuncio
Taller de Programación en C
2008-II
Entrada/Salida
Entrada/Salida
• Funciones de entrada/salida no son parte del
lenguaje propiamente tal
)Bibliotecas
Bibliotecas son parte del estándar ANSI C
)Biblioteca estándar: <stdio.h>
Daniel Herrera P.
[email protected]
• Bibliotecas no estándares implementan otras
funciones de entrada/salida
)Borland C: Console I/O (<conio.h>)
Flujos de datos
Flujos de texto
• Entrada/Salida vista como flujos de bytes
(streams) hacia y desde dispositivos
• Dispositivos
• Línea de texto: 0 o más caracteres terminadas
por un caracter terminador (\n)
)Teclado,
T l d pantalla,
t ll discos
di
duros,
d
adaptadores
d t d
gráficos, mouse, puertas de comunicación, redes,
otros procesos, etc.
)Terminador UNIX: \n
)Terminador DOS/Windows: \r\n
)Bibliotecas convierten automaticámente \r\n a \n
• Todos son tratados de la misma manera!
• Tamaño máximo de una línea: al menos 254
caracteres
Flujos binarios
Flujos estándares ANSI
• Usados para todo tipo de datos
• No se reconocen líneas en los datos
• No hay conversión de terminadores
• Todo programa ANSI C tiene 3 flujos de datos
predefinidos
)Entrada estándar (stdin)
` Generalmente, el teclado
)Salida estándar (stdout)
` Generalmente, la consola
)Salida de errores estándar (stderr)
` Generalmente, la consola
)Pueden ser redirigidas a otro dispositivo
©Daniel Herrera P.
1
Taller de Programación en C
2008-II
Estructura de datos FILE
Usando flujos
• Estructura de datos usada para acceso a
flujos
• Declarar punteros a FILE por cada flujo a
utilizar
• Abrir el flujo usando función fopen()
)Cada flujo usado por el programa tiene una
estructura FILE asociada
)Funciones de manejo de flujos de datos reciben
estructura FILE como argumento
)stdin, stdout y stderr son punteros a FILE
` Flujos estándares están siempre abiertos
Caracter
Entrada
fopen()
Salida
Descripcion
getchar()
putchar()
Lee/escribe un
caracter
Línea
gets()
scanf()
puts()
printf()
Sin formato
Con formato
Binario
fread()
fwrite()
Lee/escribe flujo
binario
Modos de operación
Leer
Escribir
FILE *fopen(char const *nombre, char const
*modo);
• Abre el flujo de datos nombre con el modo
indicado
)Nombre: ristra que identifica el archivo o
dispositivo a abrir
)Modo: ristra que indica el modo de operación del
flujo
Modos de operación
Agregar
Texto
“r”
“w”
“a”
Binario
“rb”
“wb”
“ab”
©Daniel Herrera P.
• Leer y/o escribir desde y hacia el flujo
• Cerrar el flujo con fclose()
)Libera estructura FILE
Usando flujos
Tipo de dato
)Tipo
Ti d
de acceso d
deseado
d (lectura,
(l t
escritura,
it
ambos)
• Archivo a leer debe existir; en caso contrario,
es un error
• Archivo a escribir es creado si no existe; o
truncado si existe
• Archivo a agregar (append) es creado si no
existe. Si existe, datos nuevos se agregan al
final del archivo
2
Taller de Programación en C
2008-II
fopen()
errno y perror()
• Función fopen() retorna un puntero a una
estructura FILE para el archivo
• Funciones de entrada/salida pueden generar
errores
)NULL si hubo algún error
)Variable errno refleja el tipo del error
FILE *archivo;
archivo = fopen(“datos”, “r”);
if (archivo == NULL)
exit(EXIT_FAILURE);
perror()
void perror(char const *mensaje)
• Imprime
)ristra mensaje,
)un :,: y
)una descripción del error derivada
automáticamente del valor actual de errno
Perror(“Tarea 1”);
Tarea 1: no space left on device
)Código de identificación del error se almacena en
variable entera errno (definida en <errno
<errno.h>)
h>)
)Ejemplo: error 28
` Alias: ENOSPC
` Descripción: No hay espacio disponible en el dispositivo
freopen()
• Función freopen() permite reabrir un flujo con
otro modo
FILE *freopen(char const *nombre, char const
modo, FILE *flujo);
flujo);
*modo
)Función cierra el flujo dado y lo reabre con el
nombre y modo indicados
` NULL si hubo algún error
` Si no, retorna un puntero al nuevo flujo
fclose()
getchar()
• Función fclose() cierra un flujo
• Función getchar() retorna el siguiente
caracter disponible en el flujo stdin
int fclose(FILE *flujo);
)Función cierra el flujo dado
)Vacia los buffers asociados al flujo
` EOF si hubo algún error
)0 si no lo hubo
)EOF : Constante que representa el fin del archivo
(End Of File)
©Daniel Herrera P.
int getchar(void);
)Lee un unsigned char y lo convierte a int
)Retorna EOF si no hay más caracteres a leer
)EOF si hubo algún error
• EOF no es un código ASCII!
)No cabe en un unsigned char
3
Taller de Programación en C
2008-II
getc()
feof()
• Función getc() retorna el siguiente caracter
disponible en el flujo dado
• Función feof() indica si se llegó al final del
flujo
int getc(FILE *flujo);
)Lee un unsigned char y lo convierte a int
)Retorna EOF si no hay más caracteres a leer
)EOF si hubo algún error
int feof(FILE *flujo);
)Retorna 0 si aún hay más caracteres a leer
)Retorna valor distinto de 0 si se llegó al final del
flujo
• Función fgetc() es idéntica
• Válido para flujos de texto y binarios
ferror()
putchar()
• Función ferror() indica si ocurrió un error en el
flujo
• Función putchar() envía el caracter c al flujo
stdout
int ferror(FILE *flujo);
)Retorna 0 si no hubo error
)Retorna valor distinto de 0 si ocurrió un error
• Válido para flujos de texto y binarios
int putchar(int c);
)Convierte c de int a unsigned char
)Retorna EOF si ocurrió un error
)El caracter c en caso contrario
putc()
ungetc()
• Función putc() envía caracter c al flujo f
• Función ungetc() retorna caracter c al flujo f
int putc(int c, FILE *f);
)Convierte c de int a unsigned char
)Retorna EOF si ocurrió un error
` Llamar a ferror() para flujos binarios
)El caracter c en caso contrario
)Función fputc() es idéntica
©Daniel Herrera P.
int ungetc(int c, FILE *f);
)Convierte c de int a unsigned char
)Retorna EOF si ocurrió un error
)El caracter c en caso contrario
)Anula el flag EOF
4
Taller de Programación en C
2008-II
Ejemplo
fgets()
• Procesar sólo los primeros dígitos de un flujo
• Función fgets() lee buffer_size - 1 caracteres
desde stream al buffer buffer
int c;
while((c = getchar()) != EOF && isdigit(c)) {
/* Hacer algo con el dígito */
}
ungetc(c, stdin);
char *fgets(char *buffer, int buffer_size, FILE
stream);
*stream);
)Lee sólo buffer_size – 1 caracteres
` Datos siguientes quedan en el flujo
)Lectura se detiene al encontrar un \n
` En ambos casos, agrega \n al final del buffer
fgets()
fputs()
• Función fgets() retorna NULL en caso de error
o fin de archivo
• Función fputs() escribe contenido de buffer
buf a stream
)Usar ferror() o feof() para distinguir entre estos
casos
• Tamaño mínimo del buffer es 2
)Último caracter es el \n agregado por la función
int fputs(char *buf, FILE *stream);
)Buffer debe contener una ristra terminada en
NULL
` Contenido de ristra se imprime tal cual
)En caso de error, función retorna EOF
` En caso de éxito, retorna valor no negativo
gets()
puts()
• Función gets() lee caracteres desde stdin al
buffer buffer
• Función puts() escribe contenido de buffer buf
a stdout
char *gets(char *buffer);
)gets() no almacena el caracter \n
)gets() no define largo del buffer
` Fácil sobreescribir memoria
int puts(char *buf);
)puts() agrega un caracter \n al flujo
` En caso de error, función retorna EOF
` En caso de éxito, retorna valor no negativo
)NUNCA USAR gets()
` Usar fgets(buffer, buffersize, stdin)
©Daniel Herrera P.
5
Taller de Programación en C
2008-II
Ejemplo
scanf()
• Copiar líneas de stdin a stdout
• Funciones scanf() leen caracteres con un
formato dado desde un flujo
#include <stdio.h>
#define MAXLINE 1024
char buf[MAXLINE];
while(fgets(buf, MAXLINE, stdin) != NULL) {
fputs(buf, stdout);
}
int scanf(char const *format, . . .);
int fscanf(FILE *ff, char const *format
format, . . .);
);
int sscanf(char const *ristra, char const *format, . .
.);
scanf()
scanf()
• Función scanf() lee caracteres de la entrada
estándar stdin
• Función sscanf() lee caracteres de una ristra
• Función
ó fscanf()
f
f() lee caracteres de un flujo
f
dado
• Función scanf() requiere punteros a áreas de
memoria que reciben los datos leídos
)Variables
)Ristras
)Punteros
)Retornan el número de conversiones exitosas
)EOF, al encontrar fin del flujo
Formato de scanf()
Códigos de formato scanf()
• Función scanf() recibe un formato como
argumento, que puede contener
• Formato comienza con %, al que sigue:
)Caracteres de espacio en blanco
` Espacio,
Espacio tab,
tab retorno de carro,
carro avance de línea,
línea etc.
etc
)Códigos de formato
)Otros caracteres
` Entrada debe ajustarse a estos caracteres
scanf(“ %d:%f\n”, &a, &b);
©Daniel Herrera P.
)Asterisco (opcional): indica que valor leído es
desechado
)Ancho (opcional): no puede ser negativo
` Si no está presente, se lee hasta el siguiente espacio
en blanco
)Calificador (opcional)
` h, l ó L
)Código de formato
6
Taller de Programación en C
2008-II
Formato de scanf()
printf()
%c: caracter
%d: entero decimal
%i: decimal con base
%u: decimal sin signo
g
%o: octal sin signo
%x, %X: hexadecimal
sin signo
• %p: puntero
• Funciones printf() escriben caracteres con un
formato dado en un flujo
•
•
•
•
•
•
• %f: punto flotante
• %e, %E: punto flotante
con formato E
• %g, %G: punto flotante
con formato G (%f ó
%e)
• %s: ristra
• %: el caracter %
printf()
• Función printf() escribe caracteres en la
salida estándar stdout
• Función sprint() escribe caracteres en una
ristra
• Función fprintf() escribe caracteres en un
flujo dado
int printf(char const *format, . . .);
int fprintf(FILE *ff, char const *format
format, . . .);
);
int sprintf(char const *ristra, char const *format, . .
.);
printf()
• Función sprintf() no especifica el tamaño del
buffer donde almacenar los datos
)Puede causar problemas si buffer es muy
pequeño
• Códigos de formatos de printf() similares pero
no iguales a scanf()
)Posible fuente de erorres
)Retornan el número de caracteres escritos
)Si hubo error, retornan un número negativo
fread()
fwrite()
• Función fread() lee count elementos desde el
flujo stream al buffer buf
• Función fwrite() escribe count elementos
desde el buffer buf al flujo stream
size_t fread(void *buf, size_t size, size_t count,
FILE *stream);
stream);
)Cada elemento tiene tamaño size (en bytes)
)Retorna número de elementos leídos
` Si es diferente de count, ocurrió un error
` Llamar a feof() o a ferror()
©Daniel Herrera P.
size_t fwrite(void *buf, size_t size, size_t count,
FILE *stream);
stream);
)Cada elemento tiene tamaño size (en bytes)
)Retorna número de elementos escritos
` Si es diferente de count, ocurrió un error
` Llamar a feof() o a ferror()
7
Taller de Programación en C
2008-II
Ejemplo
struct VALOR {
long a;
float b;
char
h c[SIZE];
[SIZE]
} datos[NUMERO];
numLeidos = fread(datos, sizeof(struct VALOR),
NUMERO, input);
©Daniel Herrera P.
8
Descargar