fgets () no está preguntando al usuario por segunda vez

Así es como está escrito el código.

int main() { char enteredName[30]; char stringNum[4]; char continueLetter = 0; int continueProgram = 0; int enteredAge; int i; do { memset(enteredName,'\0', 30); printf("Please enter a name: "); fgets(enteredName, 29, stdin); printf("\n\nNow please enter your age: "); fgets(stringNum, 3, stdin ); for(i = 0; i < 30; i++) { if (enteredName[i] == '\n') { enteredName[i] = '\0'; break; } } for(i = 0; i < 4; i++) { if (stringNum[i] == '\n') { stringNum[i] = '\0'; break; } } enteredAge = atol(stringNum); } while(); 

Cuando recorro el bucle por segunda vez, no puedo ingresar un nombre nuevo en la matriz de caracteres, simplemente pasa al siguiente indicador (la edad). A menos que este problema involucre listas enlazadas, el problema parece estar en otra cosa. ¿Podrías ayudarme a encontrar el error? ¡Gracias!

La segunda llamada de fgets deja caracteres (específicamente la nueva línea) en espera de ser leído desde la stdin si ingresa una edad de dos dígitos.

Aumente el parámetro de longitud para que coincida con el tamaño de la matriz:

 fgets(stringNum, 4, stdin); 

O mejor:

 fgets(stringNum, sizeof stringNum, stdin); 

Probablemente quieras hacer lo mismo con enteredName .

Desde la página del manual de fgets(3) :

La fgets() lee a lo más uno menos que la cantidad de caracteres especificados por el size de la secuencia dada y los almacena en la cadena de caracteres.

No necesita reservar la entrada de matriz adicional para el terminador nulo como lo está haciendo, fgets lo manejará correctamente por sí mismo.

El problema es que no estás vaciando el búfer de entrada, por eso fgets() te lleva directamente a la segunda pregunta. Este es un problema común, solo agrega fflush(stdin);//my compiler supports it después de fgets(); Aquí está el código que me ha funcionado, espero que también te funcione a ti:

EDITAR: Hay una publicación muy útil que proporciona información relacionada con fflush() . Como se describe que fflush está destinado a ser llamado a un flujo de salida. Otra mirada al progtwig, descubrí que usar sizeof puede hacer maravillas y es válido, así que he modificado el progtwig para mejor. El uso de sizeof también se describe en una de las respuestas aquí.

 #include #include int main() { char enteredName[30]; char stringNum[4]; int continueProgram=0; int i; while(continueProgram<3) { setbuf(stdout,NULL); printf("Please enter a name: "); fgets(enteredName, sizeof enteredName, stdin); printf("\n\nNow please enter your age: "); fgets(stringNum,sizeof stringNum, stdin ); for(i = 0; i < 30; i++) { if (enteredName[i] == '\n') { enteredName[i] = '\0'; break; } } for(i = 0; i < 4; i++) { if (stringNum[i] == '\n') { stringNum[i] = '\0'; break; } } //enteredAge = atol(stringNum); continueProgram++; } return 0; } 

El problema es que no sabe si la cadena que se ha leído contiene una newline o no. Si no contiene una newline , esto se leerá en la próxima llamada a fgets , dejando una cadena vacía en ella. Para evitarlo, compruebe si la línea contiene un carácter de newline al final. Si no, simplemente léelo con getchar() y Voila! (Tenga en cuenta que esta solución es válida solo para su problema, no en general). Este código se agregará después de leer la cadena stringNum .

 if(stringNum[strlen(stringNum)-1]!='\n') { getchar(); } 

Esto sucedió porque, si la edad es un dígito doble, entonces fgets leerá hasta el último dígito y no el carácter de newline . Por lo tanto, debe leerlo en caso de que el último carácter no sea \n . Si la edad es de un solo dígito, el progtwig original funciona bien.

Intenta esto siguiente código:

 if(stringNum[strlen(arr)-1]=='\n') stringNum[strlen(arr)-1]='\0'; else while(getchar()!='\n'); 

Cada vez que ingresa una edad de dos dígitos, el carácter de nueva línea que inserta mientras presiona Intro se almacena en el búfer. Lo que está haciendo este fragmento de código anterior es que verificará si el último carácter de su almacenamiento está lleno con un carácter de nueva línea, si es así, entonces lo reemplazará con el terminador nulo. De lo contrario, seguirá leyendo desde el búfer hasta que el carácter de nueva línea se elimine del búfer.

PD: Si está usando Borland, entonces tendrá fflush (stdin) para eliminar cualquier carácter adicional del búfer como lo indica PHlFounder, pero si usa gcc, este método es muy bueno.

También puede crear una función o macro para este fragmento de código y llamarla cada vez que lo necesite, por ejemplo.

 void function(char * arr) { if(arr[strlen(arr)-1]=='\n') arr[strlen(arr)-1]='\0'; else while(getchar()!='\n') }