Si la statement en mis bucles se omite en C

En la función de verificación, tengo un bucle llamado “tamaño” que es idéntico al tercer bucle en “foodSelect”, excepto que funciona de manera diferente por alguna razón. No me pide que ingrese primero, va directamente al interior y pregunta What size (L - Large, M - Medium, S - Small): Please enter S, M, or L only: Primero muestra el error, luego me solicita de nuevo la entrada. Es raro.

Fuente (porque es larga): http://pastebin.com/raw.php?i=KxrMAXaU

o fuente aquí:

 #include  #include  void menu(); void question (char choice[]); void output(char *foodChoice, char *foodSelect, char *foodSize, int *foodOrderNum, float *foodSubtotal); int verify(char *choice, char *foodChoice); void menu() { /* printf("\n"); */ printf("\nWelcome to Sunny FISH & CHIPS!\n\n"); printf("######## Fish : Haddock(K) Large(L) | $5.00\n"); printf("# FOOD # Halibut(T) Large(L) | $4.00\n"); printf("######## Chips: Cut(C) Large(L) | $2.00\n"); printf(" Ring(R) Large(L) | $3.00\n"); printf(" | \n"); printf("########## Soft Drinks(S) Large(L) | $2.00\n"); printf("# DRINKS # Coffee(C) Large(L) | $1.75\n"); printf("########## Tea(T) Large(L) | $1.50\n"); printf("---------------------------------------------\n"); printf("Note: Medium price: 80%% of large.\n"); printf(" Small price: 60%% of large.\n"); printf("TAX is 10%%.\n"); printf("More than 5 fish, 10%% discount on drink.\n"); printf("Every 10 fish purchased, get 1 free softdrink.\n"); printf(" - size of drink is according to size of fish\n"); printf("----------------------------------------------\n\n"); } int verify(char *choice, char *foodChoice) { int answer, rc = -1; if (choice == "order") { do { answer = getchar(); if (answer == 'Y' || answer == 'y') { rc = 1; } else if (answer == 'N' || answer == 'n') { rc = 0; } if (rc == -1 && answer != -1) { printf("Please enter y or n only: "); while (answer != -1 && answer != '\n') answer = getchar(); } } while (rc == -1 && answer != -1); } if (choice == "foodSelect") { do { answer = getchar(); if (foodChoice == "Fish") { do { answer = getchar(); if (answer == 'K' || answer == 'k') { rc = 1; } else if (answer == 'T' || answer == 't') { rc = 0; } if (rc == -1 && answer != -1) { printf("Please enter K or T only: "); while (answer != -1 && answer != '\n') answer = getchar(); } } while (rc == -1 && answer != -1); } if (foodChoice == "Chips") { do { answer = getchar(); if (answer == 'C' || answer == 'c') { rc = 1; } else if (answer == 'R' || answer == 'r') { rc = 0; } if (rc == -1 && answer != -1) { printf("Please enter C or R only: "); while (answer != -1 && answer != '\n') answer = getchar(); } } while (rc == -1 && answer != -1); } if (foodChoice == "Drinks") { do { answer = getchar(); if (answer == 'S' || answer == 's') { rc = 1; } else if (answer == 'C' || answer == 'c') { rc = 2; } else if (answer == 'T' || answer == 'T') { rc = 3; } if (rc == -1 && answer != -1) { printf("Please enter S, C, or T only: "); while (answer != -1 && answer != '\n') answer = getchar(); } } while (rc == -1 && answer != -1); } } while (rc == -1 && answer != -1); } if (choice == "size") { do { answer = getchar(); if (answer == 'S' || answer == 's') { rc = 1; } else if (answer == 'M' || answer == 'm') { rc = 2; } else if (answer == 'L' || answer == 'l') { rc = 3; } if (rc == -1 && answer != -1) { printf("Please enter S, M, or L only: "); while (answer != -1 && answer != '\n') answer = getchar(); } } while (rc == -1 && answer != -1); } } void question (char *choice) { char *choiceYesNo; char *foodOptions; char *foodChoice; char *foodSelect; char *foodSize; int *foodOrderNum; float *foodSubtotal; switch (choice[0]) { case 'f': foodChoice = "Fish"; foodOptions = "(K- Haddock, T- Halibut)"; break; case 'c': foodChoice = "Chips"; foodOptions = "(C- Cut, R- Ring)"; break; case 'd': foodChoice = "Drinks"; foodOptions = "(S- Softdrink, C- Coffee, T- Tea)"; break; } printf("\nDo you order %s? (Y/N): ", foodChoice); verify("order", foodChoice); printf("%s choice %s: ", foodChoice, foodOptions); verify("foodSelect", foodChoice); printf("What size (L - Large, M - Medium, S - Small): "); verify("size", foodChoice); printf("How many orders do you want? (>=0): "); scanf("%d", &foodOrderNum); output(foodChoice, foodSelect, foodSize, foodOrderNum, foodSubtotal); } void output(char *foodChoice, char *foodSelect, char *foodSize, int *foodOrderNum, float *foodSubtotal) { printf("\nYou ordered %s: %c - SIZE: %c amount ordered: %d, subtotal price: %.2lf\n\n", foodChoice, foodSelect, foodSize, foodOrderNum, foodSubtotal); } int main() { //menu(); question("drinks"); } 

Aparte del hecho de que realmente no debería comparar las cadenas con == (aunque en este caso desafortunadamente no es probable que funcione porque solo está utilizando literales de cadena), su problema es que la entrada de opciones necesita la clave de retorno ser presionado Por lo tanto, cuando obtiene un carácter para la opción del búfer de entrada, aún queda una nueva línea en él. Colocar un

 printf("answer = %d\n",answer); 

después de la primera answer = getchar(); en el lazo. Eso le indicará que ha recibido una nueva línea '\n' (10) [o posiblemente un retorno de carro '\r' (13), pero debido a lo siguiente, creo que ese no es el caso] del búfer de entrada. En el ciclo foodSelect , tienes una answer = getchar(); antes de las sentencias if, y una inmediatamente al comienzo de los bucles do-while, de modo que se borra el búfer de entrada. Pero en la twig foodSize no lo has hecho.

Después de cada elección, borra el búfer de entrada

 while((answer = getchar()) != -1 && answer != '\n); 

No recomiendo el uso de getchar() para progtwigs interactivos. Parece que no manejas los caracteres de nueva línea que van a aparecer después de todo lo que escribes. Utilice fgets() lugar.

Para aclarar lo anterior, cuando presiona algo como Y Ingresar , ha ingresado dos caracteres en la entrada estándar. La primera llamada a getchar() devolverá 'Y' , y la siguiente llamada devolverá '\n' (el carácter de nueva línea). Su código no espera este siguiente carácter de nueva línea y puede parecer que “salta” las llamadas a getchar() , cuando en realidad está devolviendo más caracteres que ingresó.

Si usa fgets() , obtiene la línea completa que el usuario escribió, incluida la nueva línea, todo al mismo tiempo. Usted (normalmente) no tendrá que preocuparse por la espera de datos adicionales en el búfer de entrada.

No puedes comparar cadenas con == . Como las cadenas son esencialmente punteros (a una matriz de caracteres), se están comparando los punteros (las direcciones reales en la memoria donde se almacenan los caracteres). Para poder comparar las cadenas carácter por carácter, debe usar una función adecuada, la opción predeterminada es strcmp .

Además, como mencionó Greg Hewgill, si usa getchar , obtendrá el comportamiento de omisión descrito en su pregunta. La razón es que para que el usuario pueda devolver el control a su código desde getchar (), debe presionar enter (así es como funciona la entrada de la consola). La tecla enter será uno de los caracteres leídos (es decir, el segundo si el usuario ingresó “y”), por lo que la comparación en el carácter fallará también cuando getchar regrese con el código de la tecla enter .