Entrada/Salida

Anuncio
Algoritmos y Lenguaje de Programación,
Sección 1
Entrada/Salida
Entrada/Salida
• Funciones de entrada/salida no son parte del
lenguaje propiamente tal
)Bibliotecas son parte del estándar ANSI C
)Biblioteca estándar: <stdio.h>
Mario Medina C.
[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, pantalla, discos duros, adaptadores
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
©Mario Medina C.
1
Algoritmos y Lenguaje de Programación,
Sección 1
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”
©Mario Medina C.
• Leer y/o escribir desde y hacia el flujo
• Cerrar el flujo con fclose()
)Libera estructura FILE
Usando flujos
Tipo de dato
)Tipo de acceso deseado (lectura, escritura,
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
Algoritmos y Lenguaje de Programación,
Sección 1
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.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);
)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)
©Mario Medina C.
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
Algoritmos y Lenguaje de Programación,
Sección 1
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
• Qué pasa si flujo es binario?
• 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
©Mario Medina C.
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
Algoritmos y Lenguaje de Programación,
Sección 1
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);
)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)
©Mario Medina C.
5
Algoritmos y Lenguaje de Programación,
Sección 1
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 *f, char const
*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() lee caracteres de un flujo
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, tab, retorno de carro, avance de línea, etc.
)Códigos de formato
)Otros caracteres
` Entrada debe ajustarse a estos caracteres
scanf(“
©Mario Medina C.
%d:%f\n”, &a, &b);
)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
Algoritmos y Lenguaje de Programación,
Sección 1
Formato de scanf()
%c: caracter
%d: entero decimal
%i: decimal con base
%u: decimal sin signo
%o: octal sin signo
%x, %X: hexadecimal
sin signo
• %p: puntero
•
•
•
•
•
•
• %f: punto flotante
• %e, %E: punto flotante
con formato E
• %g, %G: punto flotante
con formato G (%f ó %e)
• %s: ristra
• %: el caracter %
printf()
• Funciones printf() escriben caracteres con
un formato dado en un flujo
int printf(char const *format, . .
.);
int fprintf(FILE *f, char const
*format, . . .);
int sprintf(char const *ristra, char
const *format, . . .);
Ejemplo
int a, b, c;
scanf(“%4d %4d %4d”, &a, &b, &c);
Ante la entrada 12345 67890, retorna
a = 1234
b = 5
c = 6789
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
)Retornan el número de caracteres escritos
)Si hubo error, retornan un número negativo
printf()
Formato de printf()
• Función sprintf() no especifica el tamaño
del buffer donde almacenar los datos
• Función printf() recibe un formato como
argumento, que puede contener
)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
)Caracteres de espacio en blanco
` Espacio, tab, retorno de carro, avance de línea, etc.
)Códigos de formato
)Otros caracteres
` Son impresos sin cambios
printf(“Hora = %h:%m%s\n”, h, m, s);
©Mario Medina C.
7
Algoritmos y Lenguaje de Programación,
Sección 1
Códigos de formato de printf
Formatos de printf()
• Formato comienza con %, al que sigue:
• %c: caracter sin signo
• %d, %i: entero
decimal
• %u: decimal sin signo
• %o: octal sin signo
• %x, %X: hexadecimal
sin signo
• %p: puntero
)Modificador de conversión (opcional)
` h, l ó L
)Ancho (opcional): no puede ser negativo
` Especifica el número mínimo de caracteres
)Precisión (opcional)
)Modificador (opcional)
)Código de formato
Formatos de printf()
Formatos de printf()
Código
1
-12
12345
1234567
%d
1
-12
12345
1234567
%6d
……………1
… … … -12
… 12345
1234567
%.4d
0001
-0012
12345
%6.4d
… … 0001
… -0012
… 12345
%-4d
1………
-12 …
12345
1234567
%04d
0001
-012
12345
1234567
%+d
+1
-12
+12345
+1234567
Código
A
ABC
ABCDEFGH
%s
A
ABC
ABCDEFGH
1234567
%5s
… … … …A
… … ABC
ABCDEFGH
1234567
%.5s
A
ABC
ABCDE
%5.5s
… … … … A … … ABC
ABCDE
%-5s
A … … … … ABC … …
ABCDEFGH
fread()
Formatos de printf()
Código
1
0.01
0.00012345
12345.6789
%f
1.000000
0.010000
0.000123
12345.678900
%10.2
f
… … … … … …1.00
… … … … … …0.01
… … … … … …0.00
… …12345.68
%e
1.000000e+00
1.000000e-02
1.234500e-04
1.234568e+04
%.4e
1.0000e+00
1.0000e-02
1.2345e-04
1.2346e+04
%g
1
0.01
0.00012345
12345.7
©Mario Medina C.
• %f: punto flotante
• %e, %E: punto flotante
con formato E
• %g, %G: punto flotante
con formato G (%f ó %e)
• %s: ristra
• %: el caracter %
• Función fread() lee count elementos
desde el flujo stream al buffer buf
size_t fread(void *buf, size_t size,
size_t count, FILE *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()
8
Algoritmos y Lenguaje de Programación,
Sección 1
fwrite()
• Función fwrite() escribe count elementos
desde el buffer buf al flujo stream
size_t fwrite(void *buf, size_t size,
size_t count, FILE *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()
Ejemplo
struct VALOR {
long a;
float b;
char c[SIZE];
} datos[NUMERO];
numLeidos = fread(datos, sizeof(struct
VALOR), NUMERO, input);
fflush()
ftell()
• Función fflush() fuerza escritura de los
datos en buffers del sistema al flujo stream
• Función ftell() retorna la posición actual
del puntero al flujo stream
int fflush(FILE *stream);
)Garantiza la consistencia de los datos
` Buffers son también escritos al cerrar el archivo
long ftell(FILE *stream);
)Retorna la posición en el archivo en bytes
)Retorna -1 en caso de error
)Retorna 0 en caso de éxito
` EOF si ocurrió un error
fseek()
fseek()
• Función fseek() cambia la posición actual
del puntero al flujo stream
• Cambiando el puntero al archivo
int fseek(FILE *stream, long offset,
int from);
)Campo from:
` SEEK_SET: desde el comienzo del archivo
` SEEK_CUR: desde la posición actual
` SEEK_END: desde el final del archivo
` Retorna 0 en caso de éxito
©Mario Medina C.
)Cambiar posición a antes del comienzo del
archivo genera un error
)Escribir a posición después del final del archivo lo
hace crecer
)Leer de posición después del final del archivo
genera un error
)fseek() limpia flag EOF
9
Algoritmos y Lenguaje de Programación,
Sección 1
rewind()
fgetpos()
• Función rewind() hace que el puntero
apunte al comienzo del flujo stream
• Función fgetpos() lee la posición actual del
puntero en el flujo stream
void rewind(FILE *stream);
)Limpia flags de error y EOF
int fgetpos(FILE *stream, fpos_t
*posicion);
)Posición actual del puntero queda almacenada en
posicion
)Retorna 0 si no ocurrieron errores
fsetpos()
clearerr()
• Función fsetpos() define la posición actual
del puntero en el flujo stream
• Función clearerr() limpia el flag de error
void clearerr(FILE *stream);
int fsetpos(FILE *stream, fpos_t
const *posicion);
)Posición actual del puntero es leída desde
posicion
)Retorna 0 si no ocurrieron errores
remove()
rename()
• Función remove() borra un archivo
• Función rename() renombra un archivo
void remove(char const *nombre);
)Retorna 0 si hubo éxito
©Mario Medina C.
void rename(char const *nombreViejo,
char const *nombreNuevo);
)Retorna 0 si hubo éxito
10
Descargar