usar texto sintaxis significa que prototipo leer como c scanf fgets

texto - Fgets no funciona después de scanf



prototipo fgets (5)

#include <stdio.h> #include <string.h> #include <ctype.h> void delspace(char *str); int main() { int i, loops; char s1[101], s2[101]; scanf("%d", &loops); while (loops--) { fgets(s1, 101, stdin); fgets(s2, 101, stdin); s1[strlen(s1)] = ''/0''; s2[strlen(s2)] = ''/0''; if (s1[0] == ''/n'' && s2[0] == ''/n'') { printf("YES/n"); continue; } delspace(s1); delspace(s2); for (i = 0; s1[i] != ''/0''; i++) s1[i] = tolower(s1[i]); for (i = 0; s2[i] != ''/0''; i++) s2[i] = tolower(s2[i]); if (strcmp(s1, s2) == 0) { printf("YES/n"); } else { printf("NO/n"); } } return 0; } void delspace(char* str) { int i = 0; int j = 0; char sTmp[strlen(str)]; while (str[i++] != ''/0'') { if (str[i] != '' '') { sTmp[j++] = str[i]; } } sTmp[j] = ''/0''; strcpy(str, sTmp); }

Después de ingresar "bucles", a "s1" se le asignó una línea en blanco automáticamente. ¿Cómo sucede? Estoy seguro de que mi teclado funciona bien.


scanf() lee exactamente lo que le pediste, dejando lo siguiente /n del final de esa línea en el buffer donde fgets() lo leerá. Haga algo para consumir la nueva línea, o (mi solución preferida) fgets() y luego sscanf() desde esa cadena.


Vayn,

Geekoaur respondió bien tu pregunta, solo estoy señalando otro "problema" con tu código.

La línea s1[strlen(s1)] = ''/0''; es una operación nula si s1 está terminada correctamente nula ANTES de ejecutarse.

Pero si s1 NO está terminado correctamente y termina nulo ANTES de que se ejecute esta línea (y no tiene suerte), causará:

  • un SIGSEGV en un sistema POSIX (* nix).
  • un GPF en Windows.

¡Esto se debe a que strlen básicamente encuentra el índice del terminador nulo existente y lo devuelve! Aquí hay una implementación válida y no optimizada de strlen:

int strlen(char *string) { int i = 0; while(string[i] != ''/0'') { ++i; } return i; }

Entonces ... Si estás REALMENTE preocupado de que las cadenas NO tengan terminación nula, entonces harías algo como:

  • string[sizeof(string)]=''/0''; en cadenas automáticas locales (donde el compilador "conoce" el tamaño de la cadena);
  • o string[SIZE_OF_STRING] para todas las demás cadenas, donde SIZE_OF_STRING es (más comúnmente) una constante #define ''d, o una variable que usted mantiene específicamente para almacenar el TAMAÑO actual (no la longitud) de una cadena asignada dinámicamente.

Y si REALMENTE, REALMENTE, REALMENTE temen que las cadenas no terminen en nulo (como si estuvieras lidiando con métodos de biblioteca "sucios" (como el ATMI de Tuxedo, por ejemplo) TAMBIÉN "borras" tus "cadenas de devolución" antes de pasarlas a los métodos de la biblioteca sospechosa con:

  • before: memset(string, NULL, SIZE_OF_STRING);
  • DirtyFunction(/*out*/string) : DirtyFunction(/*out*/string) ;
  • after: string[SIZE_OF_STRING]=''/0''

Los SIG11 son un completo reclamo porque (a menos que los "enganche" con un procesador de señal y diga lo contrario, causan que Unix termine su programa, por lo que no puede registrar nada (después del hecho) para ayudar a descubrir donde-en-el-infierno-hizo-que-venga-desde ... especialmente teniendo en cuenta que en muchos casos la línea de código que arroja el SIG11 no está cerca de la causa real de la cadena que pierde su terminador nulo.

¿Eso tiene sentido para ti?

Salud. Keith.

PD: ADVERTENCIA: strncpy NO siempre es nulo ... probablemente strlcpy decir strlcpy . Aprendí esto de la manera difícil ... cuando se colapsó una facturación de 60 millones de dólares.

EDITAR:

FYI: Aquí hay una versión "segura" (no optimizada) de strlen que llamaré strnlen (creo que debería estar en stdlib . Suspiro).

// retuns the length of the string (capped at size-1) int strnlen(char *string, int size) { int i = 0; while( i<size && string[i]!=''/0'' ) { ++i; } return i; }


scanf deja espacios en blanco en el búfer de entrada, incluidos los caracteres de nueva línea. Para usar fgets para leer la siguiente línea, necesita eliminar manualmente el resto de la línea actual:

do{ int c = getchar(); }while(c != EOF && c != ''/n'');


Sé que esto es muy viejo. Soy nuevo en c y quería verificar mi método, que usa getchar :

#include <stdio.h> int main() { printf("Please enter your name/n"); char string[10]; scanf("%s", string); printf("Hello %s/n", string); //getchar(); # un commenting this line, fgets perfectly works!! printf("Please enter your name again/n"); fgets ( string, 10, stdin ); printf("Hello again %s", string); getchar(); }


simplemente ponga scanf("%d/n",&loops);

en lugar de scanf("%d",&loops);