Cambiar el menú de la caja

Estoy tratando de hacer un progtwig que le solicite al usuario un menú de opciones como esta

***************************************************************** Enter the number corresponding to the desired pay rate or action: 1) $8.75/hr 2) $9.33/hr 3) $10.00/hr 4) $11.20/hr 5) quit ***************************************************************** 

Y luego calcule el salario neto, el salario bruto y los impuestos, de acuerdo con la tasa de pago. Tengo todas las tarifas de pago hechas, pero el menú real de las tarifas me está dando problemas. Si el usuario ingresa 5, debe salir y si ingresa cualquier otra cosa, de 1 a 5, recicle y vuelva a preguntar por la opción correcta. Tengo un problema para reciclar si la entrada es distinta de 1 a 5.

 #include "stdafx.h" #include "stdio.h" #include "stdlib.h" #include "ctype.h" #define HOURLY0 8.75 #define HOURLY1 9.33 #define HOURLY2 10 #define HOURLY3 11.20 #define TAXRATE .15 #define TAXRATE2 .20 #define TAXRATE3 .25 #define OVERTIME 15 int _tmain(int argc, _TCHAR* argv[]) { float hours, grossPay = 0, netPay, tax = 0, tax3 = 0,hourly; int menu = 0,wrong =1; char quit; printf("Enter the number corresponding to the desired pay rate or action : \n\n1) $8.75/hr 2) $9.33/hr \n3) $10.00/hr 4) $11.20/hr \n5) quit\n\n"); scanf_s("%d", &menu); while (menu != 5 ) { do { switch (menu) { case 1: hourly = HOURLY0; break; case 2: hourly = HOURLY1; break; case 3: hourly = HOURLY2; break; case 4: hourly = HOURLY3; break; default: printf("Enter right choice from 1 to 5 only\n"); printf("Enter the number corresponding to the desired pay rate or action : \n\n1) $8.75/hr 2) $9.33/hr \n3) $10.00/hr 4) $11.20/hr \n5) quit\n\n"); scanf_s("%d", &menu); wrong; break; } } while (!wrong);/* HOW CAN I MAKE IT TO RECYCLE IF INPUT IS OTHER THAN 1-5*/ printf("\nEnter hours worked in the week: "); scanf_s("%f", &hours); if (hours > 40) { grossPay = (40 * hourly) + ((hours - 40) * OVERTIME); if (grossPay  300 && grossPay  450) { tax3 = grossPay - 450; tax = (300 * TAXRATE) + ((grossPay - 300 - tax3)*TAXRATE2) + ((grossPay - 300 - 150)*TAXRATE3); } } else if (hours < 40) { grossPay = (hours * hourly); if (grossPay  300 && grossPay  450) { tax3 = grossPay - 450; tax = (300 * TAXRATE) + ((grossPay - 300 - tax3)*TAXRATE2) + ((grossPay - 300 - 150)*TAXRATE3); } } netPay = grossPay - tax; printf("\nGross Pay : %2.3f\nTax: %13.3f\nNet Pay: %10.3f\n\n", grossPay, tax, netPay); system("cls"); printf("Enter the number corresponding to the desired pay rate or action : \n\n1) $8.75/hr 2) $9.33/hr \n3) $10.00/hr 4) $11.20/hr \n5) quit\n\n"); scanf_s("%d", &menu); } system("pause"); return 0; } 

Una forma de mejorar el código es mover el procesamiento de entrada del usuario a una subrutina. De esa manera, todo el manejo de errores desordenados entra en la subrutina y main solo tiene que procesar entradas válidas.

En el código a continuación, la función GetUserInput repetirá para siempre, hasta que el usuario ingrese un número válido o se produzca un final de archivo o un error en el scanf . El valor de retorno de GetUserInput solo puede ser un valor de 1 a 5, por lo que main no necesita manejar ningún valor inesperado.

 int GetUserInput( void ) { int menu; for (;;) { menu = 0; printf("Enter the number corresponding to the desired pay rate or action : \n\n1) $8.75/hr 2) $9.33/hr \n3) $10.00/hr 4) $11.20/hr \n5) quit\n\n"); if ( scanf( "%d", &menu ) != 1 ) exit( 1 ); if ( menu >= 1 && menu <= 5 ) return menu; printf( "Enter right choice from 1 to 5 only\n" ); } } int main( void ) { int menu = 0; while ( menu != 5 ) { menu = GetUserInput(); switch ( menu ) { case 1: printf( "\n*** You selected 1 ***\n\n" ); break; case 2: printf( "\n*** You selected 2 ***\n\n" ); break; case 3: printf( "\n*** You selected 3 ***\n\n" ); break; case 4: printf( "\n*** You selected 4 ***\n\n" ); break; case 5: printf( "Bye\n" ); break; } } } 

Cuando usa scanf() debe tener en cuenta que cuando un usuario ingresa un valor, scanf intenta leer solo lo que escribe en el especificador de formato, el rest aún permanece en el búfer. Por lo tanto, escribir “% d” significa que lee el número, pero que queda en el búfer es \ n.

Ahora, cuando más tarde realice otra exploración, el \ n todavía está en el búfer, por lo que la exploración devuelve directamente 0.

En su lugar, use fgets() para leer el valor del teclado en una cadena de caracteres, luego use sscanf() o atoi() para recuperar el número entero.

p.ej

 char buffer[256]; while (fgets(buffer,sizeof(buffer),stdin)!=NULL) { if (sscanf(buffer, "%d", &n) == 1) { switch(n) {...} } else { ... some error output ... } } 

Después del bucle while (! Incorrecto) , si ha puesto su comentario, agregue:

 if(wrong) continue; //restart from the outer-while 

e inicie incorrecto = 0 al principio y ajústelo a 1 en la opción predeterminada de cambio .