esta función se ejecuta demasiadas veces

Por qué si escribo alguna otra letra o número (no y \ n) el pedido

printf("\nWould you like to play again? (y/n):"); 

correr dos veces?

 int ans= 0,i=1; do { printf("\nWould you like to play again? (y/n):"); ans = getchar(); if (ans=='y') { printf("yyyyyyyyyyy"); i = i-1; } else if ( ans == 'n') { printf("nnnnnnnnnnn"); i=i-1; } else { printf("not y or n"); } } while(i); 

El while(i) es efectivamente el mismo que while(i != 0) . Si ingresa algo que no sea y o n , el bloque else se ejecuta y no cambia el valor de i . Como i=1 antes del bucle, i es distinto de cero si ingresa algo que no sea y o n . Tratar:

 else { printf("not y or n"); i = i-1; // <---- new line } 

Probablemente porque tu llamada getchar está recogiendo la nueva línea de tus comentarios. Entonces, si presiona ‘X’, la primera vez que pasa por el bucle ans es ‘X’ y la nueva línea se almacenó en búfer. La segunda vez a través del bucle ans es ‘\ n’.

Puede poner un bucle alrededor de su llamada de entrada de esta manera:

 do ans = getchar(); while (isspace(ans)); 

Esto es demasiado complicado. Como indicó en un comentario, solo desea realizar un bucle hasta que se haya escrito y o no . No hay necesidad de una variable extra. En general, para tales problemas es una mala idea usar un contador. Más a prueba de fallos está utilizando una bandera bool .

Un buen enfoque sin variable auxiliar sería:

 int ans; // no need to initialise, as it is set before the first read do { printf("Play again?"); do { ans = getchar(); } while ( ans == `\n` ); ... } while ( (ans != EOF) && !strchr("yYnN", ans) ); 

Ver strchr Añadí tolerancia para las letras mayúsculas.

Tenga en cuenta que siempre verifica EOF, también. Como eso no se puede representar como un char , debe probarse por separado y primero (de lo contrario, la conversión en strchr puede producir resultados inesperados).

También tenga en cuenta que el fflush de entrada (que se puede encontrar en algún código en Internet) es un comportamiento indefinido, no lo use. Incluso si algunas bibliotecas lo toleran, es posible que no se comporten como se espera (lo que está implícito en un comportamiento indefinido ). Enjuague en general como la semántica de “escribir / enviar” datos. La entrada normalmente se “cae” (y no hay función fdrop .

Edición: Se agregó un bucle interno para eliminar caracteres de nueva línea Sin eso, el bucle se ejecutará dos veces después de ingresar un carácter no válido. Esto supone que debe ingresar un carácter por línea.

No importa qué letra escriba antes de presionar Entrar , la línea

 c = getchar(); 

Todavía deja el carácter de nueva línea en el flujo de entrada.

Si el carácter es distinto de y y n , esa llamada se ejecuta sin esperar por usted y el carácter de nueva línea se asigna a c . Por lo tanto, ves salida de las siguientes líneas dos veces.

 printf("\nWould you like to play again? (y/n):"); 

y

 printf("not y or n"); 

Debe agregar código para ignorar el rest de la línea de la entrada después de

 c = getchar(); 

Añadir una función:

 void ignoreRestOfLine() { int c; while ( (c = getchar()) != EOF && c != '\n'); } 

y llamalo como:

 c = getchar(); ignoreRestOfLine(); 

Otra solución:

 char c = 'x'; // Initialize to a character other than input while( c != 'y' || c != 'n') { // You can also use strchr as @Olaf mentioned printf ("\nPlay again (y/n): "); c = getchar (); } 

El problema es que cuando entras en el progtwig nuevamente en la tarea mientras ya hay una respuesta en la memoria. getchar() agrega un \ ny eso es lo que queda. para evitar esto, puede hacer ans un carácter (char) lo que significa que estará leyendo la tabla ascii; (y = 121 yn = 110). Char no coloca una \ n (nueva línea) después de recibir la entrada, para asegurarse de que esto ocurra, debe dejar un espacio antes de% c como scanf(" %c", &ans); esto significa que ans está recibiendo un int.

 #include #include int main(void){ char ans; int i = 1; do { printf("\nWould you like to play again? (y/n):"); scanf(" %c", &ans); if (ans == 121){ printf("yyyyyyyyyyy"); i = i - 1; } else if ( ans == 110){ printf("nnnnnnnnnnn"); i = i - 1; } else{ printf("not y or n"); } } while(i); }