Notas Especiales

Función fflush

Ejemplo 1: Si ejecutamos el siguiente programa:

por pantalla veremos algo parecido a:

Obsérvese que, cuando se ejecuta scanf, por ejemplo, en la primera vez scanf( "%d", &a ); el programa se detiene a la espera de que el usuario teclee el dato de entrada requerido, el cual es almacenado, temporalmente, en el buffer (memoria intermedia) de la entrada estándar. Y cuando se pulsa la tecla INTRO, es, en ese momento, cuando a la variable a se le asigna el valor introducido. Pero, además, se produce un salto de línea automático, de forma que, después de introducir el número 76, la siguiente instrucción se muestra una línea más abajo. De igual forma, después de la instrucción scanf( "%d", &b ); también se produce un salto de línea automático. En este ejemplo todo ha ido muy bien, sin embargo, se tiene que tener especial cuidado si utilizados scanf para leer caracteres.

Ejemplo 2: En el siguiente programa:

por pantalla se verá algo similar a:

En esta ocasión, ¿por qué no se ejecuta, correctamente, la siguiente instrucción: scanf( "%c", &b ); La razón es la siguiente: cuando se ejecuta la primera instrucción de entrada:

scanf( "%c", &a );

después de asignar el carácter 'f' a la variable a, se produce un salto de línea automático, pero, en el buffer del teclado también se ha quedado almacenada la secuencia de escape (\n), que es, precisamente, un carácter. En consecuencia, cuando se ejecuta la instrucción scanf( "%c", &b );  a la variable b se le asigna el salto de línea almacenado en el buffer de la entrada estándar, y la ejecución del programa continua con la siguiente instrucción. Ahora, el buffer vuelve a estar vacío y, por tanto, la entrada de la variable c sí que se ejecuta de forma correcta.

Para comprobar que esto es así, podemos sustituir la instrucción: printf( "Los valores son: %c, %c, %c ", a, b, c ); por esta otra: printf( "Los valores son: %d, %d, %d ", a, b, c );

En pantalla veremos:

y como se puede comprobar en las tablas del ASCII, los números 102, 10 y 104 corresponden a los caracteres 'f', LF (Salto de Línea) y 'h', respectivamente.

Para resolver este problema, antes de leer un carácter con scanf, hay que vaciar (limpiar) el buffer del teclado. Para ello, se utiliza la función fflush.

Ejemplo 3: De forma que, el código quedaría de la siguiente manera:

La primera vez que se ejecuta scanf, el buffer del teclado está vacío, por tanto, no es preciso utilizarfflush, pero sí, en los dos casos posteriores. Obsérvese que, a fflush hay que indicarle el buffer a limpiar, Standar Input (stdin) en este caso.

Captura de cadenas con espacios

Con el formato %s no es posible capturar cadenas que incluyan espacios, por ejemplo un nombre de persona “Benito Juárez” se esperaría capturar con un scanf(“%s”,cadena), pero entre el nombre y el apellido existe un espacio y al capturarlo con scanf no se almacenan ambos valores; tal vez se buscaría capturar con la función gets(cadena), pero seguiríamos con el mismo problema, por lo que es necesario hacer uso del formato %[].

Esto funciona de distintas formas:

1) Es posible escribir entre los corchetes el conjunto de caracteres que se pueden aceptar, por ejemplo: scanf("%[a-z]",cadena); 
Esta instrucción captura caracteres que estén entre la 'a' y la 'z' y en cuanto encuentre un caracter distinto terminará la captura.

2) Otro ejemplo es la instrucción: scanf("%[^.]",cadena); 
Esta instrucción captura todo tipo de caracteres incluyendo el espacio, excepto el punto.

3) La instrucción scanf("%[^\n]",cadena); permite capturar una cadena con espacios y dejará de capturar hasta que se pulse la tecla enter.