在函数验证中,我有一个名为“size”的循环,它与“foodSelect”中的第3个循环相同,只是因为某些原因它的工作方式不同。它不会先提示我输入,它会直接转到if里面并询问What size (L - Large, M - Medium, S - Small): Please enter S, M, or L only:
。它首先显示错误,然后再次提示我输入。这很奇怪。
来源(因为它很长):http://pastebin.com/raw.php?i=KxrMAXaU
或来源:
#include <stdio.h>
#include <string.h>
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");
}
答案 0 :(得分:4)
我不建议将getchar()
用于交互式程序。您似乎没有处理在您键入的所有内容后出现的换行符。请改用fgets()
。
为了澄清上述内容,当您按下 Y Enter 之类的内容时,您已将两个字符输入到标准输入中。第一次调用getchar()
将返回'Y'
,下一个调用将返回'\n'
(换行符)。您的代码不会指望此后续换行符,并且可能会“跳过”对getchar()
的调用,而实际上它会返回您输入的更多字符。
如果您使用fgets()
,则会立即获得用户键入的整个行,包括换行符。您(通常)不必担心在输入缓冲区中等待额外的数据。
答案 1 :(得分:2)
您无法将字符串与==
进行比较。由于字符串本质上是指针(对于字符数组),因此您要比较指针(存储字符的内存中的实际地址)。为了逐个字符地比较字符串,您需要使用适当的函数,默认选择为strcmp
。
另外,正如Greg Hewgill所说,如果您使用getchar
,您将获得问题中描述的跳过行为。原因是为了让用户从getchar()中控制回代码,他们需要按enter
(这是控制台输入的工作方式)。键enter
将是读取的字符之一(即,如果用户输入“y”,则为第二个),因此当getchar
返回enter
的代码时,字符上的比较也将失败{1}}密钥。
答案 2 :(得分:1)
除了你真的不应该将字符串与==
进行比较之外(尽管在这种情况下,不幸的是,由于你只使用字符串文字而不太可能,因此你的麻烦)是因为选择条目需要按 return 键。因此,当您从输入缓冲区中获取选择的一个字符时,仍然会有一个换行符。放置一个
printf("answer = %d\n",answer);
在循环中的第一个answer = getchar();
之后。这会告诉你,你已经获得了换行符'\n'
(10)[或者可能是回车'\r'
(13),但由于以下原因,我认为并非如此]来自输入缓冲区。在foodSelect
循环中,在if语句之前有一个answer = getchar();
,在do-while循环的开头有一个,因此清除了输入缓冲区。但是在foodSize
分支中你还没有。
每次选择后,清除输入缓冲区
while((answer = getchar()) != -1 && answer != '\n);