03 – Entrada y salida en lenguaje C Diego Andrés Alvarez Marín Profesor Asociado Universidad Nacional de Colombia Sede Manizales 1 Temario ● Entrada/salida básica (stdio.h) ● Entrada/salida avanzada (ncurses.h) 2 Funciones de salida/entrada de datos básicas ● ● Las provee la librería estándar stdio.h y no el lenguaje mismo. stdio.h significa "standard input-output header" (cabecera estandar E/S) – stdin = standard input = teclado – stdout = standard output = pantalla – stderr = standard error 3 Funciones básicas de salida a pantalla (stdout) ● ● Sin formato: – putchar() escribe un caracter a stdout – puts() escribe una cadena de caracteres a stdout Con formato: – printf() escribe una cadena de caracteres con formato a stdout 4 int putchar(int ch); ● Escribe un caracter en la pantalla (stdout) ● Retorna ch 5 int puts(const char* str); Escribe la cadena str a stdout y agrega automáticamente un “\n”. La cadena str termina cuando se encuentra un caracter “\0”. El “\0” no se copia a stdout 6 int printf(const char* formato,...) ); printf() retorna el número de caracteres impresos, o un valor negativo si ocurre un error. printf() toma un número variable de entradas 7 int printf(const char* formato,...) formato en printf() ● ● Es una cadena de texto que indica el formato como se debe escribir lo deseado Sigue el siguiente prototipo: %[banderas][ancho][.precisión][longitud]especificador Ver detalles en: http://pubs.opengroup.org/onlinepubs/009695399/function http://en.cppreference.com/w/cpp/io/c/fprintf http://en.wikipedia.org/wiki/Format_string_attack 8 %[banderas][ancho][.precisión][longitud]especificador Introducido en C99 Introducido en C99 Introducido en C99 9 %[banderas][ancho][.precisión][longitud]especificador %[flags][width][.precision][longitud]especificador 10 %[banderas][ancho][.precisión][longitud]especificador Introducido en C99 Introducido en C99 Introducido en C99 Introducido en C99 Introducido en C99 11 12 Hacer ejemplo de printf con \a \b \t 13 Funciones básicas de entrada desde el teclado (stdin) ● ● Sin formato: – getchar() lee un caracter desde stdin – gets() lee una cadena de caracteres desde stdin (C99 – desaconseja su uso, C11 – obsoleto) – gets_s() lee una cadena de caracteres desde stdin (es el reemplazo de gets()) Con formato: – scanf() lee una cadena de caracteres con formato desde stdin 14 int scanf(const char* formato, ...); ● ● ● ● Lee datos del teclado (stdin) y lo almacena de acuerdo al formato dado, en las direcciones de memoria indicadas. De forma a similar a printf() puede leer un número variable de entradas; en este caso se supone que cada entrada está separada por un espacio en blanco Ignora los espacios en blanco Retorna el número de items de la cadena de argumentos exitosamente leídos. 15 int scanf(const char* formato, ...); ● El formato está dado por: %[*][ancho][longitud]especificador ● Ver detalles en: http://en.cppreference.com/w/cpp/io/c/fscanf 16 %[*][ancho][longitud]especificador C99 C99 C99 17 %[*][width][length]especificador 18 Observe este comportamiento inesperado!! 19 | 20 int getchar(void); Lee un caracter desde el teclado (mostrándolo). 21 char* gets (char* str); ● El C99 no recomienda usar este comando. El C11 lo vuelve obsoleto. La razón de esto es que este comando hace vulnerable el programa al ataque por hackers. Ver detalles en: – http://en.cppreference.com/w/c/io/gets – http://en.wikipedia.org/wiki/Buffer_overflow 22 char* gets (char* str); Buffer overflow!! 23 char* gets_s(char *str, rsize_t n); ● ● ● Función sugerida en el C11, en reemplazo de gets() Lee a lo más n-1 caracteres de stdin en la cadena apuntada por str. Automáticamente agrega el \0 al final de la cadena No está implementada todavía en el gcc v.4.6 (el que tengo en mi computador) 24 Otro reemplazo de gets(): fgets() strchr() busca desde la dirección buf hasta que encuenta la primera aparición de un \n 25 Nota con respecto a la entrada de datos desde el teclado scanf() no es muy versátil que digamos. La mejor opción que se tiene si se requiere seguridad procesando la entrada es utilizar fgets() y alguna librería de regular expressions: http://en.wikipedia.org/wiki/Regular_expression No existen librerías de expresiones regulares en el estándar de C, pero si algunas para ciertos sistemas como regex.h o PCRE para UNIX/Linux: http://www.lemoda.net/c/unix-regex/index.html http://www.pcre.org/ Se podría también utilizar una interface con el comando de consola grep. 26 27 NOTA: lenguajes como PERL, PYTHON, MATLAB tienen un muy buen soporte para expresiones regulares. Les aconsejo sinceramente aprender a manejar las expresiones regulares cuando tengan problemas con validar entradas de texto, o procesar una gran cantidad de datos en archivos. Es una herramienta que los puede sacar de apuros en más de una ocasión. 28 Tomado de: http://xkcd.com/208/ Funciones de salida/entrada de datos básicas <ncurses.h> ● ● ● curses.h es una biblioteca que provee rutinas de entrada/salida avanzadas y que permite al programador escribir interfaces basadas en texto. Fue creada por Ken Arnold para el sistema UNIX BSD. Sin embargo, existen implementaciones para Linux (ncurses.h) y para Windows (pdcurses.h). Permite manejar detalladamente la pantalla, manejar el mouse, crear interfaces de texto 29 amigables. Tomada de: http://dmcradio.sourceforge.net/ 30 31 Instalación en Windows de pdcurses ● Descargue de: http://pdcurses.sourceforge.net/ ● Lea las instrucciones de instalación. ● O si está utilizando el MinGW, simplemente en la línea de comandos escriba: mingw-get install mingw32-libpdcurses mingw32-pdcurses 32 En Linux ● Instale la librería libncurses5-dev o similar, ej.: $ sudo apt-get install libncurses5-dev ● Verifique que los siguientes archivos existan: ● ● ● ● ● Observe que en este caso ncurses.h y curses.h son el mismo archivo 33 Un primer ejemplo Si no se pone este comando, la consola se comportará de modo extraño. En linux esto se arregla con el comando de consola reset. De todos modos se debe poner siempre endwin(). 34 35 36 Otros comandos de curses.h ● int addch(const chtype letra_char); ● int mvaddch(int y, int x, const chtype letra_char); ● int move(int y, int x); ● chtype inch(void); ● int mvprintw(int y, int x, char *format, ...); ● int getstr(char* string); 37 Material basado en: ● http://www.slideshare.net/amraldo/introduction-to-c-programming-7898353 ● http://www.slideshare.net/petdance/just-enough-c-for-open-source-program ● http://www.cplusplus.com/reference/cstdio/printf/ ● http://www.cplusplus.com/reference/cstdio/scanf/ ● http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1049157810&id ● Wikipedia