scanf
La función scanf
permite leer varios tipos de
datos de una sola vez, tales como enteros, números decimales o cadenas de
caracteres.
#include <stdio.h> int scanf(const char *format,...);
Aquí se pueden indicar varios especificadores de formato
en la variable de tipo puntero format
, dependiendo del tipo
que se quiere leer, como con printf
. Si todo va bien,
devuelve el número de datos leídos. Si hay algún error, devuelve
EOF
.
Si usamos el especificador %s
para leer una
cadena, la función lee caracteres hasta encontrar un espacio, un intro, un
tabulador, un tabulador vertical o un retorno de carro. Los caracteres que
lee se guardan en un array que debe ser lo suficientemente grande como
para almacenarlos. Añade el carácter nulo al final automáticamente.
Al igual que pasaba con gets
, es muy
peligroso usar scanf
para leer cadenas, pues
scanf
no tiene en cuenta la longitud de lo leído y admitirá
que el usuario escriba más caracteres que lo que el array definido en el
programa pueda admitir. Como resultado, scanf
escribirá los
caracteres que ya no quepan en el array definido en otras porciones de
memoria que pueden contener otros datos que está usando nuestro
programa. Esto desembocará en comportamientos anómalos, en fugas de
memoria, etc. Más tarde veremos cómo poder leer cadenas de caracteres de
manera más segura.
Con scanf
, a diferencia de
printf
, hay que pasar punteros a los
argumentos para que scanf
pueda modificar sus
valores.
El siguiente programa muestra el uso de scanf
para distintos especificadores de formato.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdio.h> #define TAM_MAXIMO 80 int main(void) { char cadena[TAM_MAXIMO]; int entero1, entero2; float decimal; printf("Introduce dos enteros separados por un espacio: \n"); scanf("%d %d", &entero1, &entero2); printf("Introduce un número decimal:\n"); scanf("%f", &decimal); printf("Introduce una cadena:\n"); scanf("%s",cadena); printf("Esto es todo lo que has escrito:\n"); printf("%d %d %f %s\n",entero1,entero2,decimal,cadena); return 0; } |
Nota que en la línea 15 usamos scanf
para
leer una serie de caracteres, y esos caracteres (más el caracter de
terminación de cadena) se guardan en el array apuntado por
cadena
. Sin embargo, aquí no se utiliza el operador de
dirección &
, porque el propio nombre de un array
(cadena
en este caso), apunta (es equivalente) a la dirección
de comienzo del propio array.