Si quiere descargar la presentación y los códigos fuente, dirijase a:
http://programaciondecomputadoresunalmzl.wikispaces.com/codigos_y_diapositivas
Le agradecería si me reporta los errores que encuentre en la diapositiva (daalvarez arroba unal punto edu punto co)
3. 3
Buffer
Un buffer (de datos) es un espacio de memoria, en el que se
almacenan datos para evitar que el programa o recurso que los
requiere, ya sea hardware o software, se quede sin datos durante una
transferencia.
Un buffer es como tener dinero en el banco (buffer), un trabajo
(entrada) y unos gastos fijos (salida). Si tienes un trabajo inestable,
mientras tengas ciertos ahorros, puedes mantener tus gastos fijos sin
problemas, e ir ingresando dinero cuando puedas según vas
trabajando. Si los ahorros son pequeños, en seguida que no tengas
trabajo, no vas a poder acometer los gastos fijos. De la misma forma si
escuchas música en Internet y tu programa de audio usa un buffer
pequeño, en cuanto que haya alguna interrupción en la descarga
(porque las descargas nunca tienen una velocidad constante), notarás
cortes de sonido, ya que faltará información.
El buffer de teclado es una memoria intermedia en la que se van
almacenando los caracteres que un usuario teclea, los cuales son
tratados por el computador apenas se libere un recurso.
4. 4
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
5. 5
Funciones básicas de salida a
pantalla (stdout)
● Sin formato:
– putchar() escribe un carácter a stdout
– puts() escribe una cadena de caracteres a stdout
● Con formato:
– printf() escribe una cadena de caracteres con
formato a stdout
7. a r
Backspace b f
t ”
Escape (solo GNU) e n
o x
Backslash '
0 ?
Alerta (audible) Retorno de carro
Formfeed
Tabulador horizontal Comillas
Cambio de linea=rf
Número octal (ej: o32) Número hex (ej: xF3)
Apóstrofe
Nulo Pregunta
Algunos caracteres especiales
8.
9. 9
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
carácter “0”. El “0” no se copia a stdout
10. 10
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
11. 11
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/functions
http://en.cppreference.com/w/cpp/io/c/fprintf
http://en.wikipedia.org/wiki/Format_string_attack
16. 16
Un bug en MinGW
En Windows existe un bug en las funciones printf() y
scanf() con el formato tipo long o long long; por ejemplo:
scanf ("%llu n", &x); o printf("%llu n", x);
Generan el warning:
warning: unknown conversion type character 'l' in
format [-Wformat]
La solución es usar #include<inttypes.h> y
scanf("%"SCNu64"",&x); // entre comillas
printf("%"PRIu64"",UINT64_MAX);
Más información en:
http://stackoverflow.com/questions/10763854/printf-and
19. El estándar de codificación de
caracteres UNICODE
Se diseñó para facilitar el tratamiento informático,
transmisión y visualización de textos de múltiples
lenguajes y disciplinas técnicas, además de textos
clásicos de lenguas muertas. Unicode incluye sistemas
de escritura modernos como: árabe, braille, copto,
cirílico, griego, sinogramas (hanja coreano, hanzi chino y
kanji japonés), silabarios japoneses (hiragana y
katakana), hebreo y latino; escrituras históricas extintas,
para propósitos académicos, como por ejemplo:
cuneiforme, griego antiguo, fenicio y rúnico. Entre los
caracteres no alfabéticos incluidos en Unicode se
encuentran símbolos musicales y matemáticos, fichas de
juegos como el dominó, flechas, iconos etc.
20. El estándar de codificación de
caracteres UNICODE
● Se adoptó como norma ISO en 1993, como una
extensión de los códigos ASCII.
● Se tiene espacio para 1'114.112 símbolos posibles
(del 0x000000 al 0x10FFFF). Actualmente se usa la
versión 6.3 (Septiembre de 2013). Esta versión define
más de 110.000 símbolos.
● Los puntos de código se representan utilizando
notación hexadecimal agregando el prefijo U+. El
valor hexadecimal se completa con ceros hasta 4
dígitos hexadecimales cuando es necesario; si es de
longitud mayor que 4 dígitos no se agregan ceros.
21. Los símbolos UNICODE
http://www.unicode.org/charts/
● Se escriben como U+XXXXXX donde X es un
hexadecimal (esto se llama el code point).
● En C se representa tal Unicode como uXXXX (hasta
4 hexadecimales) o como UXXXXXX (hasta 6
hexadecimales)
● En GNU/Linux se escribe con Ctrl+Shift+u+codepoint
ENTER. Cuando esto se hace la letra u aparece
subrayada. Se debe tener una fuente apropiada
instalada.
● En MS Windows: ver la utilidad "charmap". Se debe
tener una fuente apropiada instalada.
24. 24
Funciones básicas de entrada
desde el teclado (stdin)
● Sin formato:
– getchar() lee un carácter 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
25. 25
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 o un EOF
(constante igual a -1) si un error ocurre.
26. 26
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
32. 32
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
– http://c-faq.com/stdio/getsvsfgets.html
33. 33
char* gets (char* str);
Buffer overflow!!
Dirección char hex
0xbfd8935b 1 E 45
0xbfd8935c 2 j 6A
0xbfd8935d 3 e 65
0xbfd8935e 4 m 6D
0xbfd8935f 5 p 70
0xbfd89360 6 l 6C
0xbfd89361 7 o 6F
0xbfd89362 8 s 73
0xbfd89363 9 0 00
7565164 = 0x00736F6C
m.buf
m.i
Codificación
Little-endian
del número
entero m.i
34. 34
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,
porque este aún no incorpora los cambios
sugeridos en el C11
36. 36
¿Por qué este código
aparentemente
correcto no funciona?
Se presionó 20 (ENTER) y nada más.
El programa no me preguntó el nombre y terminó
37. 37
Aquí el primer printf() pregunta la edad. Se escribe "20"
y se presiona ENTER. El buffer del teclado contiene:
2 0 n
El scanf() lee el %d, es decir el 20 y lo guarda en la
variable edad; sin embargo deja el 'n' en el buffer del
teclado; ahora entra el fgets() lee el 'n' y no alcanza a
leer el nombre. El problema es que scanf() dejó basura
en el buffer del teclado (concretamente el n).
Según http://c-faq.com/stdio/gets_flush2.html la solución
es vaciar el buffer del teclado lo cual se puede hacer
con alguno de los siguientes comandos:
● while((c = getchar()) != 'n' && c != EOF); //un ciclo vacío
● __fpurge(stdin); //solo funciona con gcc/Linux (stdio_ext.h)
● flushinp(); // si está manejando la librería curses.h
39. 39
Nota con respecto a la entrada de
datos desde el teclado
scanf() no es muy versátil que digamos y tiene problemas
como el anteriormente mostrado. La mejor opción que se
tiene si se requiere seguridad procesando la entrada es
utilizar fgets(), sscanf() y/o 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.
41. 41
Tomado de: http://xkcd.com/208/
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.
42. 42
Preferiblemente no use scanf()
http://c-faq.com/stdio/scanfprobs.html
Una buena interface debe permitir la posibilidad
que el usuario entre errores: por ejemplo letras en
un campo donde se piden números, más o menos
caracteres que los esperados, etc. scanf() no es
capaz de tratar este tipo de situaciones. Por lo
tanto, se sugiere mejor utilizar fgets() y luego
interpretar lo leído utilizando sscanf() y/o algunas
otras técnicas como expresiones regulares.
Funciones como strtol(), strtok(), y atoi() son
bastante útiles.
43. 43
La librería inttypes.h
Cuando se quieren imprimir (printf())o leer
(scanf()) el tipo de números definidos en stdint.h,
se deben ajustar las cadenas de texto con los
formatos, para que funcionen con estos tipos de
datos. inttypes.h se encarga de esto.
Tenga en cuenta que la librería inttypes.h llama
automáticamente a stdint.h
44. 44
Los símbolos de printf() y scanf()
definidos por inttypes.h
El N en cursiva es 8, 16, 32 o 64 bits
45. 45
Ejemplo con inttypes.h
Desde este punto de vista PRIx8 es un formato que se le agrega a
printf() para que este muestre hexadecimales de 8 bits.
Observe que se utilizó implícitamente la concatenación de cadenas.
46. 46
Funciones de salida/entrada de
datos básicas <curses.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
amigables.
49. 49
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
54. 54
Configuración del PDCURSES en
Codeblocks para Windows
Si le aparece este error copie el archivo libpdcurses.dll en
la misma carpeta donde está el archivo .exe de su
proyecto.
55. 55
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
56. 56
Tutorial de ncurses.h
● Se sugiere mirar el siguiente tutorial:
http://www.tldp.org/HOWTO/NCURSES-Programming-HOWTO/
● Los siguientes programas están basados en
dicho tutorial.
57. 57
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().
ncurses.h en linux
curses.h en windows -lncurses en linux
-lpdcurses en windows
63. 63
Uso del mouse con ncurses.h
Ver el código:
http://programaciondecomputadoresunalmzl.wikispaces.com/file/detail/03_mouse_curses.c
64. 64
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);
65. 65
Programación de juegos
Existen varias librerías especialmente diseñadas
para programar juegos. Estas librerías contienen
funciones para el manejo de gráficos 2D y 3D,
sonidos, joystick, etc. Algunas de las más
populares son:
Allegro: http://alleg.sourceforge.net/
ClanLib: http://clanlib.org/wiki/Main_Page
OpenGL: http://www.opengl.org/
SDL: http://www.libsdl.org/
SFML: http://www.sfml-dev.org/
66. 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
● http://www.tldp.org/HOWTO/NCURSES-Programming-HOWTO/
● Wikipedia