2

¿Por qué parece que algunas instrucciones son ignoradas? Al intentar leer, no lee nada.

Por ejemplo, en un código como el siguiente:

int n;
char linea[20];

scanf("%i", &n);
fgets(linea, sizeof(linea), stdin);
printf("Número: %i, Línea: %s", n, linea);

Es como si el fgets fuese pasado por alto.

O de manera similar con cin.getline en C++:

int n;
char linea[20];

cin >> n;
cin.getline(linea, sizeof(linea));
cout << "Número: " << n << " Línea: " << linea;

1 respuesta 1

2

Cada vez que intentamos leer la entrada del programa, el mismo se pone en espera a que el usuario introduzca más información. Al terminar, para que el programa siga ejecutándose es necesario presionar Enter. Esto también agrega un salto de línea en la entrada y en algunas ocasiones puede ser un efecto indeseado.

gets, fgets, cin.getline y getline no descartan el espacio en previo. Leen hasta encontrar un salto de línea (inclusive). Por lo que llamar a la misma función 2 o más veces seguidas no dará ningún problema.

cin >> x y la mayoría de especificadores de scanf descartan el espacio previo pero no el posterior, así que el último salto de línea permanece. Si justo después se utiliza gets o alguna de las otras 3 funciones, inmediatamente lo encuentran y se obtiene una cadena vacía. Esto da la sensación de que la instrucción estuviera siendo omitida pero no es así.

La solución es consumir el salto de línea antes. Algunas opciones son:

  • La más simple y posiblemente la mejor, scanf(" ") elimina todo el espacio que haya quedado en la entrada.
  • Solo en C++, cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') ignora todos los caracteres hasta encontrar un salto de línea.
  • cin.ignore() sin parámetros solo ignora 1 caracter así que no es una solución efectiva. Si el usuario escribe espacios antes de presionar Enter, el salto de línea no se eliminará y el problema persistirá.
  • fflush solo debería usarse con streams de salida pero se puede encontrar código usando fflush(stdin). Esta solución no es portable ya que solo funciona en ciertos compiladores. Más información.

Con scanf, los especificadores de %[], %c y %n no ignoran el espacio previo. La mejor solución es agregar un espacio justo antes del especificador. Por ejemplo: scanf(" %c").

Como curiosidad, el Scanner de Java tampoco se salva. Antes de usar nextLine es posible que sea necesario consumir el salto de línea con scanner.skip("\\s") o algún patrón similar.

¿No es la respuesta que buscas? Examina otras preguntas con la etiqueta o formula tu propia pregunta.