Utilizando scanf y obtiene simultáneamente.

Sé que estoy haciendo una pregunta básica. Tengo problemas con el uso de scanf y me scanf en un progtwig en C. Cuando estoy usando scanf , scanf no funciona. El ejemplo está abajo:

 void fun() { char str[10]; printf("Enter the string"); gets(str); printf("Entered string is %s\n", str); } int main() { int val; printf("Enter the value\n"); scanf("%d", &val); fun(); } 

Si ejecuto este progtwig, gets no está realizando. Después de introducir el valor. No está esperando para entrar en la cadena. La salida es Enter the stringEntered string is . Pero si comenta el scanf , espera a que la entrada se gets y funcione correctamente. ¿Alguien puede decirme, qué hice mal.

Bueno, la respuesta “correcta” aquí es simple: nunca se usa. Es así de simple. Incluso se ha eliminado de la norma C11.

La razón es que no tiene forma de limitar la cantidad de entrada, por lo que no importa cuán grande sea el búfer que reserve, el usuario todavía puede generar suficiente entrada para provocar un desbordamiento del búfer.

Probablemente debería usar fgets , si está escribiendo el estándar C. Debe usar getline si usa gcc (como MinGW o Cygwin en Windows), o cualquier sistema operativo moderno similar a Unix con soporte para el estándar POSIX lo suficientemente reciente.


Entonces a la pregunta real, haciendo caso omiso de los problemas con. El problema es que scanf deja el rest de la línea, incluida la presión de entrada en el flujo de entrada. Una solución robusta es escribir una función, que leerá la entrada hasta la próxima nueva línea, algo como esta función no probada:

 // this function reads given file until newline or end of file or error, // and returns last value read int eatLine(FILE *fp) { for(;;) { int ch = getc(fp); if (ch == '\n' || ch < 0) return ch; } } 

Uso:

 if (scanf("%d", &myint) != 1) exit(0); // exit on invalid input if (eatLine(stdin) < 0) exit(0); // read and ignore rest of the line, exit on eof 

Existen otras soluciones, como leer una línea para almacenar en búfer y usar sscanf en ella, la anterior es solo una posibilidad fácil.

Intente reemplazar scanf("%d", &val) con scanf("%d%*c", &val) .

La página del manual dice que para %c :

Se suprime el salto habitual de los espacios en blanco iniciales.

%c por lo tanto, hace coincidir la nueva línea después del valor y deja el búfer vacío.

De esa manera, cuando se llega a la rutina de fun() , se gets entrada de espera.

El * en %*c significa que no necesita almacenar el carácter en una variable (felicitaciones a @CoolGuy por señalarlo).