Algo muy usual en un programa es esperar que el usuario introduzca datos por el teclado. Para ello contamos con varias posibilidades: Usar las funciones de la biblioteca estándar, crear nuestras propias interrupciones de teclado (MS-Dos) o usar funciones de alguna biblioteca diferente (como por ejemplo Allegro).
Nosotros en este capítulo vamos a estudiar la primera, usando las funciones de la biblioteca estándar. Pero veamos por encima las otras posibilidades.
Las funciones estándar están bien para un programa sencillito. Pero cuando queremos hacer juegos por ejemplo, no suelen ser suficiente. Demasiado lentas o no nos dan todas las posibilidades que buscamos, como comprobar si hay varias teclas pulsadas. Para solucionar esto tenemos dos posibilidades:
La más coplicada es crear nuestras propias interrupciones de teclado. ¿Qué es una interrupción de teclado? Es un pequeño programa en memoria que se ejecuta contínuamente y comprueba el estado del teclado. Podemos crear uno nuestro y hacer que el ordenador use el que hemos creado en vez del suyo. Este tema no lo vamos a tratar ahora, quizás en algún capítulo posteror.
Otra posibilidad más sencilla es usar una biblioteca que tenga funciones para controlar el teclado. Por ejemplo si usamos la biblioteca Allegro, ella misma hace todo el trabajo y nosotros no tenemos más que recoger sus frutos con un par de sencillas instrucciones. Esto soluciona mucho el trabajo y nos libra de tener que aprender cómo funcionan los aspectos más oscuros del control del teclado.
Vamos ahora con las funciones de la biblioteca estándar.
El uso de scanf es muy similar al de printf con una diferencia, nos da la posibilidad de que el usuario introduzca datos en vez de mostrarlos. No nos permite mostrar texto en la pantalla, por eso si queremos mostrar un mensaje usamos un printf delante. Un ejemplo:
#include <stdio.h> int main() { int num; printf( "Introduce un número " ); scanf( "%i", &num ); printf( "Has tecleado el número %i\n", num ); return 0; }
Primero vamos a ver unas nota de estética, para hacer los programas un poco más elegantes. Parece una tontería, pero los pequeños detalles hacen que un programa gane mucho. El scanf no mueve el cursor de su posición actual, así que en nuestro ejemplo queda:
Introduce un número /* La barra horizontal indica dónde esta el cursor */
Esto es porque en el printf no hemos puesto al final el símbolo de salto de línea '\n'. Además hemos dejado un espacio al final de Introduce un número: para que así cuando tecleemos el número no salga pegado al mensaje. Si no hubiésemos dejado el espacio quedaría así al introducir el número 120 (es un ejemplo):
Introduce un número120
Bueno, esto es muy interesante pero vamos a dejarlo y vamos al grano. Veamos cómo funciona el scanf. Lo primero nos fijamos que hay una cadena entre comillas. Esta es similar a la de printf, nos sirve para indicarle al compilador qué tipo de datos estamos pidiendo. Como en este caso es un integer usamos %i. Después de la coma tenemos la variable donde almacenamos el dato, en este caso 'num'.
Fíjate que en el scanf la variable 'num' lleva delante el símbolo &, este es muy importante, sirve para indicar al compilador cual es la dirección (o posición en la memoria) de la variable. Por ahora no te preocupes por eso, ya volveremos más adelante sobre el tema.
Podemos preguntar por más de una variable a la vez en un sólo scanf, hay que poner un %i por cada variable:
#include <stdio.h> int main() { int a, b, c; printf( "Introduce tres números: " ); scanf( "%i %i %i", &a, &b, &c ); printf( "Has tecleado los números %i %i %i\n", a, b, c ); return 0; }
De esta forma cuando el usuario ejecuta el programa debe introducir los tres datos separados por un espacio.
También podemos pedir en un mismo scanf variables de distinto tipo:
#include <stdio.h> int main() { int a; float b; printf( "Introduce dos números: " ); scanf( "%i %f", &a, &b ); printf( "Has tecleado los números %i %f\n", a, b ); return 0; }
A cada modificador (%i, %f) le debe corresponder una variable de su mismo tipo. Es decir, al poner un %i el compilador espera que su variable correspondiente sea de tipo int. Si ponemos %f espera una variable tipo float.
Si lo que queremos es que el usuario introduzca un caracter por el teclado usamos las funciones getch y getche. Estas esperan a que el usuario introduzca un carácter por el teclado. La diferencia entre getche y getch es que la primera saca por pantalla la tecla que hemos pulsado y la segunda no (la e del final se refiere a echo=eco). Ejemplos:
#include <stdio.h> int main() { char letra; printf( "Introduce una letra: " ); fflush( stdout ); letra = getche(); printf( "\nHas introducido la letra: %c", letra ); return 0; }
Introduce una letra: a Has introducido la letra: a
Quizás te estés preguntando qué es eso de fflush( stdout ). Pues bien, cuando usamos la función printf, no escribimos directamente en la pantalla, sino en una memoria intermedia (lo que llaman un bufer). Cuando este bufer se llena o cuando metemos un carácter '\n' es cuando se envia el texto a la pantalla. En este ejemplo yo quería que apareciera el mensaje Introduce una letra: y el cursor se quedara justo después, es decir, sin usar '\n'. Si se hace esto, en algunos compiladores el mensaje no se muestra en pantalla hasta que se pulsa una tecla (pruébalo en el tuyo). Y la función fflush( stdout ) lo que hace es enviar a la pantalla lo que hay en ese bufer.
Y ahora un ejemplo con getch:
#include <stdio.h> int main() { char letra; printf( "Introduce una letra: " ); fflush( stdout ); letra = getch(); printf("\n has introducido la letra :%c", letra ); return 0; }
Resultado:
Introduce una letra: Has introducido la letra: a
Como vemos la única diferencia es que en el primer ejemplo se muestra en pantalla lo que escribimos y en el segundo no.
Ejercicio 1: Busca el error en el siguiente programa:
#include <stdio.h>
int main() {
int numero;
printf( "Introduce un numero: " );
scanf( "%d", numero );
printf( "\nHas introducido el numero %d.\n", numero );
return 0;
}
Solucion:
A la variable numero le falta el '&' con lo que no estamos indicando al programa la direccion de la variable y no obtendremos el resultado deseado. Haz la prueba y veras que el mensaje "Has introducido el numero X" no muestra el numero que habias introducido.
© Gorka Urrutia