es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo resolver definitivamente el problema de la corriente de entrada de scanf

Supongamos que quiero ejecutar el siguiente fragmento de código en C:

scanf("%d", &some_variable);
printf("algo algo\n\n");

printf("Presione [enter] para continuar...")
getchar(); //colocado para darle tiempo al usuario de leer el "algo algo"

¡Este fragmento no se pausará! El problema es que scanf dejará el carácter “enter” (\n) en el flujo de entrada1, arruinando todo lo que viene después; en este contexto, getchar() se comerá el \n y no esperará un nuevo carácter real.

Dado que me dijeron que no use fflush(stdin) (realmente no entiendo por qué), la mejor solución que se me ocurrió es simplemente volver a definir la función scanf al comienzo de mi código:

void nsis(int *puntero){ //nsis: siglas de "no shenanigans integer scanf"
     scanf("%d", puntero);
     getchar(); //esto limpiará el flujo de entrada cada vez que se llame a la función scan
}

Y luego simplemente usamos nsis en lugar de scanf. Esto debería funcionar. Sin embargo, parece una solución casera y parcheada, ¿cómo manejan este lío los desarrolladores profesionales de C? ¿No usan scanf en absoluto? ¿Aceptan trabajar con un flujo de entrada sucio? ¿Cuál es el estándar en este caso?

No pude encontrar una respuesta definitiva en ninguna parte. Cada fuente que encontré mencionaba una solución diferente (y dudosa)…


EDITAR: En respuesta a todos los que comentan alguna versión de “simplemente no uses scanf”: está bien, puedo hacer eso, pero ¿cuál es el propósito de scanf entonces? ¿Es simplemente una función inútil y rota que nunca se debería usar? ¿Por qué está en las bibliotecas en primer lugar?

Esto parece realmente absurdo, especialmente considerando que a todos los principiantes se les enseña a usar scanf


[1]: El \n que queda es el que el usuario escribió al ingresar el valor de la variable some_variable y no el presente en printf.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    La función scanf en C es una función ampliamente utilizada para tomar la entrada del usuario. Sin embargo, como se mencionó en la pregunta, puede dejar caracteres no deseados en el flujo de entrada, lo que puede causar problemas al intentar tomar la entrada nuevamente o leer desde el flujo de entrada. Hay algunas formas de solucionar este problema:

    1. Usar fflush(stdin): Hay debates sobre si esta es una solución segura o no, ya que el comportamiento de fflush(stdin) no está definido en el estándar de C. Algunos compiladores pueden implementarlo mientras que otros no. Por lo tanto, es mejor evitar su uso.
    2. Usar fgets en lugar de scanf: fgets permite leer la entrada como una cadena hasta una longitud especificada, y deja de leer al final de la línea, incluido el carácter de nueva línea. Por lo tanto, no deja caracteres no deseados en el flujo de entrada. Luego, la entrada se puede convertir al tipo de datos deseado utilizando funciones como strtol. Sin embargo, en comparación con scanf, fgets requiere más líneas de código y más verificación de errores.

    3. Escribir una función de entrada personalizada: Como se muestra en la pregunta, se puede crear una función de entrada personalizada que lea la entrada usando scanf y luego llame a getchar para limpiar el flujo de entrada. Este enfoque es más conciso que usar fgets, pero aún requiere verificación de errores y puede no ser adecuado para escenarios de entrada más complejos.

    En resumen, aunque scanf es una función útil para tomar entrada, tiene sus limitaciones y puede causar problemas con el flujo de entrada. Los desarrolladores profesionales de C pueden usar alternativas como fgets o funciones de entrada personalizadas para manejar la entrada del usuario.

Comments are closed.