UC3M

Grado en Ing. Telemática/Sist. Audiovisuales/Sist. de Comunicaciones

Arquitectura de Sistemas

Septiembre 2017 - Enero 2018

8.3.3. La función 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.

Nota

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.