Este es un comúnmente discutido tema, llena de opinión, pero muy interesante, nada menos. He observado que una gran mayoría de aquellos que ya han respondido a preguntas similares en este sitio caer en el lado de fgets()
. Yo soy uno de ellos. Me parece fgets()
mucho mejor la de usar para el usuario de entrada de scanf()
con pocas excepciones. scanf()
es considerado por muchos como sub-método óptimo para el manejo de la entrada del usuario. Por ejemplo
"...se le dirá si tuvo éxito o no, pero se puede decir que sólo aproximadamente, donde se produjo el error, y no en todos, cómo o por qué. Usted
tienen muy poca oportunidad de recuperación de errores."
(jamesdlin). Pero en el interés de procurar el equilibrio, va a empezar citando esta discusión.
Para la entrada de usuario que viene de stdin
, es decir, la entrada de teclado, fgets()
será una mejor opción. Es mucho más permisiva en que la cadena se lee puede ser validados antes de la conversión se intenta
Uno de los pocos momentos en que el uso de un formulario de scanf(): fscanf() estaría bien podría ser cuando la conversión de la entrada de un muy controlados en origen, es decir, a partir de la lectura estrictamente un formato de archivo con la repetición de predicción de los campos.
Para más discusión, esta comparación de los dos aspectos más destacados adicionales ventajas y desventajas de ambos.
Edit: a la dirección de OP pregunta adicional acerca de desbordamiento:
"Una cosa más que quiero preguntar es: incluso cuando usar fgets ¿qué sucede si el usuario ingresa los caracteres más de límite (me refiero a un montón de
los personajes), conduce al desbordamiento de búfer? Entonces, ¿cómo lidiar con
es así?"
[fgets()](https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm está muy bien diseñado para evitar desbordamiento de búfer, simplemente mediante el uso de sus parámetros correctamente, por ejemplo:
char buffer[100] = {0};
...
while fgets(buffer, sizeof buffer, stdin);
Esto impide la entrada mayor que el tamaño de búfer de ser procesados, evitando el desbordamiento.
incluso el uso de scanf()
la prevención de desbordamiento de búfer es bastante sencillo: Usar un especificador de ancho en la cadena de formato. Si quieres leer la entrada, por ejemplo, y el límite de tamaño de entrada de un usuario a 100 caracteres como máximo, el código se incluyen las siguientes:
char buffer[101] = {0};// includes space for 100 + 1 for NULL termination
scanf("%100s", buffer);
^^^ width specifier
Sin embargo, con los números, desbordamiento no es tan agradable de usar scanf()
. Para demostrar el uso de este simple código, la introducción de los dos valores indicados en el comentario de uno por ejecutar:
int main(void)
{
int val = 0;
// test with 2147483647 & 2147483648
scanf("%d", &val);
printf("%d\n", val);
return 0;
}
Para el segundo valor, el sistema arroja el siguiente:
NON-FATAL RUN-TIME ERROR: "test.c", line 11, col 5, thread id 22832: Function scanf: (errno == 34 [0x22]). Range error
`
Aquí usted necesita para leer una cadena de texto, a continuación, siga con una cadena a número de la conversión de uso de uno de los strto_()
funciones: strtol(), strtod(), ...). Incluyen la capacidad de la prueba para el desbordamiento antes de causar un tiempo de ejecución de advertencia o de error. Tenga en cuenta que el uso de atoi()
, atod()
no va a proteger de desbordamiento de cualquiera.