¿Usando scanf y fgets en el mismo progtwig?

Necesito hacer algo como lo siguiente:

int main(void) { char a,b,cstring; printf("please enter something"); scanf("%c %c",&a,&b); prinf("thanks, now some more"); fgets(cstring,35,stdin); } 

El problema es que cada vez que entro en las primeras variables de scanf, se salta al final del progtwig. ¿Cómo hago entradas múltiples?

El primer problema es que el scanf() lee dos caracteres, pero no la nueva línea después.

Eso significa que tus fgets() leen la nueva línea y terminan.

Tienes suerte de que tu progtwig no esté fallando. Le dices a fgets() que está obteniendo una matriz de 35 caracteres, pero en lugar de pasar una matriz, pasas el carácter (no la dirección de un carácter, incluso). Eso también nos dice que no está incluyendo #include (no puede usar scanf() manera confiable de acuerdo con el estándar C sin un prototipo para scanf() en el scope), y no está comstackndo con suficientes advertencias habilitadas , o no prestar suficiente atención a lo que su comstackdor le está diciendo.

Deberías estar recibiendo advertencias del comstackdor. Por ejemplo, GCC 4.6.0 dice:

 /usr/bin/gcc -g -I/Users/jleffler/inc -std=c99 -Wall -Wextra -Wmissing-prototypes \ -Wstrict-prototypes -Wold-style-definition xxx.c xxx.c: In function 'main': xxx.c:7: warning: implicit declaration of function 'prinf' xxx.c:8: warning: passing argument 1 of 'fgets' makes pointer from integer without a cast 

Y, maldita sea, ni siquiera había notado el error ortográfico de prinf() para printf() hasta que intenté enlazar y el comstackdor me frotó la nariz diciendo “¡No sé qué es prinf() !”.

Si su comstackdor no da al menos la segunda advertencia, consígase un mejor comstackdor.


Comentario:

¿Cómo puedo evitar que lea la nueva línea después de ella?

El problema no es impedir que scanf() lea la nueva línea; el problema es en realidad cómo hacerlo leer de manera que fgets() obtenga una ejecución clara en la siguiente línea de entrada. En realidad, es modestamente complicado, una de las razones por las que rara vez uso scanf() (pero a menudo uso sscanf() ). Esto hace el trabajo para entradas simples:

 #include  int main(void) { char a,b,cstring[35]; printf("please enter something"); scanf("%c %c%*c", &a, &b); printf("thanks, now some more"); fgets(cstring, 35, stdin); printf("OK: I got %c and %c and <<%s>>\n", a, b, cstring); return 0; } 

El %*c lee un carácter adicional (una nueva línea) sin asignarlo a ningún lugar (eso es debido a * ). Sin embargo, si hay varios caracteres después del segundo espacio en blanco, no sirve de ayuda. Probablemente escribiría un bucle para leer a la nueva línea:

 #include  int main(void) { char a,b,cstring[35]; int c; printf("please enter something"); scanf("%c %c", &a, &b); while ((c = getchar()) != EOF && c != '\n') ; printf("thanks, now some more"); fgets(cstring, 35, stdin); printf("OK: I got %c and %c and <<%s>>\n", a, b, cstring); return 0; } 

Tenga en cuenta que getchar() devuelve un int y no un char . Esto descarta de manera confiable todo en la primera línea de entrada. También muestra cómo hacer eco de lo que lee, una parte importante de la depuración.

Eso es un comportamiento indefinido. Su variable de cstring , a pesar de su nombre, es un solo carácter, y está intentando leer hasta 35 caracteres a lo que apunta su valor actual. En otras palabras, el carácter actual en cstring se convertirá en un puntero e intentará escribir su entrada allí. Esa será una ubicación de memoria (lo más probable) entre 0 y 255 inclusive.

Eso es lo que está causando tu violación de segmentación. Comience con algo como esto en su lugar:

 #include  int main(void) { char a,b,cstring[99]; printf("please enter something"); scanf("%c %c",&a,&b); printf("thanks, now some more"); fgets(cstring,35,stdin); return 0; } 

O, posiblemente, mejor:

 #include  int main(void) { char a,b,cstring[99]; printf("please enter something"); fgets(cstring,35,stdin); sscanf(cstring,"%c %c",&a,&b); printf("thanks, now some more"); fgets(cstring,35,stdin); return 0; } 

O, si desea una solución más robusta para las aportaciones de los usuarios, consulte aquí . Es un método probado y con muy buena comprobación de errores.

El problema es que cuando el flujo llega a fgets (), esta API primero busca la entrada estándar para la entrada y encuentra un ‘\ n’ callejero allí. En cuanto a fgets () que dijo que esta API devuelve cuando encuentra EOF o ‘\ n’, dado que fgets () obtuvo ‘\ n’ de stdin, se ejecutó sin esperar a que el usuario ingrese algo cuando se cumplen las condiciones de retorno de la API.

La solución al problema es que usas getchar (); después de scanf e ignora los caracteres adicionales dejados por scanf (). p.ej:

 scanf("%lf",&e); getchar(); fgets(t,200,stdin); 

o

Otra solución puede ser usar sscanf con fgets. p.ej:

 #include  int main() { int j;char t[200]; fgets(t,200,stdin); sscanf(t,"%d",&j); } 

Puedes usar fflush (stdin) después de usar scanf, lo que soluciona el problema