Entrada de Datos. Lenguaje C
SOLUCIONARIO
Entrada de Datos. Lenguaje C
2026-03-29
Por
Occam's Razor

#include <stdio.h>

int
main (void)
{
  int  n, t, i;
  int  a[10];

  printf ("Introduce dos numeros separados por un espacio ?");
  scanf ("%d %d", &n, &t);
  printf ("Has introducido %d y %d\n", n, t);

  printf ("Introduce 10 numeros separados por espacios?\n");
  for (i = 0; i < 10; scanf ("%d", &a[i++]));

  printf ("Has introducido: ");
  for (i = 0; i < 10; i++) printf ("%d ", a[i]);
  printf ("\n"); 

  return 0;
}

La forma más sencilla y directa de leer datos del usuario en C es utilizando la función de la librería estándar scanf. Esta función utiliza format strings (o cadenas de formato) idénticas a printf para leer información del usuario y convertirla automáticamente al formato que nos interese, en este ejemplo en enteros.

La función scanf requiere el uso del operador &. Este operador en C nos permite acceder al puntero a la variable que indicamos, es decir, a la posición de memoria en la que se encuentra. Su nombre es Address-of, o Dirección de. Sin entrar en más detalles, en C, debemos utilizar este operador para los parámetros de salida de las funciones…. cada vez que necesitamos modificar el valor de una variable dentro de una función.

SOY NOVATO

C solo permite llamar a las funciones por valor. En este modo, se hace una copia de los valores de los parámetros, los cuales se pasan a la función para que haga su trabajo. Sin embargo, puesto que estamos pasando una copia de los valores de los parámetros, cualquier cambio que hagamos en la función se aplicará sobre la copia y no afectará a la variable original.

Para conseguir esto, es necesario llamar a la función por referencia. En este caso en lugar de la copia del valor del parámetro, pasamos una referencia al mismo, de forma que podamos modificarlo dentro de la función. En C esto se consigue pasando el puntero a la variable, utilizando el operador &. Estrictamente hablando, seguimos llamando a la función por valor, solo que ahora el valor es una referencia. Otros lenguajes, permiten diferenciar entre estas dos modalidades de forma más clara.

Como veremos en breve, uno de los problemas al leer información del usuario es que la forma que tiene el usuario de indicar al ordenador que ha terminado de escribir sus datos es pulsando la tecla ENTER. Dependiendo de la forma de obtener esta entrada del usuario, puede ser que el caracter \n (la tecla ENTER) esté presente en el resultado y sea necesario eliminarlo. Utilizando la función scanf no tenemos este problema…. Otro gallo cantaría si hubiéramos utilizado fgets.

¿SABÍAS QUÉ?

Nuestro programa puede obtener fácilmente los datos de un fichero en lugar de desde la consola simplemente redirigiendo el fichero a la entrada estándar del programa.

$ cat <<EOM | ./input
> 3 4
> 0 1 2 3 4 5 6 7 8 9
> EOM
Introduce dos números separados por espacios? Has introducido 3 y 4
Introduce 10 números separados por espacios ?
0 1 2 3 4 5 6 7 8 9

Si bien, el uso de scanf es muy útil para ejemplos sencillos, en el mundo real, esta función es bastante problemática por cuestiones como el manejo de los retornos de carro que mencionamos anteriormente. En estas situaciones es mejor leer la cadena completamente y parsearla de forma específica para detectar errores.

En nuestro sencillo ejemplo, si pulsamos enter tras introducir 3 o 4 valores, el programa funcionará igual pero no mostraría un error. Posteriores scanf en el programa se confundirían y leerían datos incorrectos.

Una forma más correcta sería leer todo el texto en un buffer, y luego parsear los datos según nuestras necesidades. Por ejemplo:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main (void)
{
  int  i;
  int  a[10];
  char buf[1024], *aux, *end;

  printf ("Introduce 10 numeros separados por espacios?\n");
  fgets (buf, 1024, stdin);
  
  aux = strtok(buf, " ");
  for (i = 0; i < 10; i++) {
    if (!aux) {printf ("ERROR\n"); return -1;}
    a[i] = strtold (aux, &end);
    if (a[i] == 0 && end == aux) {printf ("ERROR1\n"); return -1;}
    aux = strtok(NULL, " ");
  }

  printf ("Has introducido: ");
  for (i = 0; i < 10; i++) printf ("%d ", a[i]);
  printf ("\n"); 

  return 0;
}

Este programa lee una línea completa de datos y la parsea utilizando strtok que nos permite extraer tokens de una cadena de caracteres usando el delimitador que queramos, en este caso el espacio. El bucle convierte cada token en un entero usando strtold que nos permite detectar errores en caso de que el número introducido no sea correcto (un texto por ejemplo). El programa también termina con un error si leemos menos de 10 valores. En ese caso la llamada strtok retornará NULL puesto que no hay suficientes tokens en la línea.

En general, es mejor escribir código específico para leer y manejar los posibles errores en nuestros programas C que usar la función estándar scanf.

SUMARIO

  • Podemos leer datos en nuestros programas usando la función scanf.
  • scanfrequire que pasemos los valores por referenica (punteros a los datos), para poder modificar las variables internamente.
  • Si necesitas controlar la validez de los datos entrados por el usuario, scanf no es una buena opción y es mejor implementar tu propio código para leer y parsear los datos

SOBRE Occam's Razor
Somos una revista libre que intenta explicar de forma sencilla conceptos tecnológicos y científicos de los que no podemos escapar. Al final, todo es más fácil de lo que parece!

 
Tu publicidad aquí :)