2012-03-26 109 views
1

在函數verify中,我有一個稱爲「size」的循環,它與「foodSelect」中的第3個循環相同,只是它由於某種原因工作不同。它不會首先提示我輸入,它會直接轉到if內部,並詢問What size (L - Large, M - Medium, S - Small): Please enter S, M, or L only:。它首先顯示錯誤,然後再次提示我輸入。有點奇怪。如果我的循環中的語句被跳過C

源(因爲它是長):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"); 


} 
+2

Ç不使用'不支持串的直接比較=='。改用['strcmp'](http://linux.die.net/man/3/strcmp)。另請參閱:http://stackoverflow.com/questions/6715247/what-is-the-difference-between-some-some-0-and-strcmpsome-some-0-in – 2012-03-26 22:16:57

+3

你可以把它歸結爲一個最小的測試用例?該代碼非常長。 – 2012-03-26 22:17:45

+0

提示:你不能用==比較C中的字符串 – antlersoft 2012-03-26 22:18:25

回答

1

除了你實際上不應該將字符串與==進行比較(儘管在這種情況下,由於只使用字符串文本而不太可能工作),但是您的麻煩是因爲需要輸入選項返回鍵被按下。因此,當您從輸入緩衝區中獲取一個字符作爲選擇時,仍然存在一個換行符。放置一個

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

之後的第一個answer = getchar();在循環中。這將告訴你,你已經從輸入緩衝區獲得換行'\n'(10)[或者可能是回車'\r'(13),但是因爲以下原因,我認爲情況並非如此]。在foodSelect循環中,if語句之前有一個answer = getchar();,並且在do-while循環的開始處有一個answer = getchar();,這樣就清除了輸入緩衝區。但在foodSize分支你沒有。

每個選擇後,清除輸入緩衝器

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

謝謝,讓它工作的部分是在我做之前將'answer = getchar()'放在一邊的建議。 – eveo 2012-03-27 23:11:56

4

我不建議使用getchar()的互動節目。您似乎無法處理您輸入的所有內容後將出現的換行符。改爲使用fgets()

爲了澄清上述情況,當你按下喜歡Ÿ東西進入,你已經進入字符到標準輸入。第一次撥打電話getchar(),將返回'Y',下一個電話將返回'\n'(換行符)。您的代碼不希望出現以下換行符,並且可能會顯示「跳過」getchar()的調用,但實際上它正在返回更多您輸入的字符。

如果您使用fgets(),那麼您將獲得整個用戶輸入的整行,包括換行符,全部一次。您(通常)不必擔心在輸入緩衝區中等待的額外數據。

+0

不能使用fgets,只能使用getchar。如果(choice ==「size」)不是我的問題,那可以正常工作,但是當它與'foodSelect'中的第3個循環幾乎相同時, 。 – eveo 2012-03-26 22:20:11

+0

當你嘗試使用'fgets()'時,你會得到一個錯誤嗎?它在''中,與'getchar()'相同,所以應該沒有問題。 – 2012-03-26 22:22:02

+0

如果你不能使用fgets來做一些糟糕的事情要求,你應該直接閱讀'\ n'o n scanf – vascop 2012-03-26 22:26:56

2

您無法將字符串與==進行比較。由於字符串本質上是指針(指向字符數組),因此您正在比較指針(存儲字符的內存中的實際地址)。爲了逐字符比較字符串,您需要使用適當的函數,缺省選項是strcmp

另外,正如Greg Hewgill所說,如果您使用getchar,您將會看到您的問題中描述的跳過行爲。原因是爲了讓用戶從getchar()控制回代碼,他們需要按enter(這是控制檯輸入的工作方式)。密鑰enter將是所讀取的字符之一(即如果用戶輸入「y」則爲第二個字符),所以當getchar返回enter密鑰的密碼時,字符的比較也會失敗。

+0

事實證明,字符串被指定爲常量並與常量進行比較,如果OP的編譯器執行常量字符串摺疊(這似乎是這種情況),那麼實際上'=='將起作用。 – 2012-03-26 22:26:49

+0

它可能是,但這是依賴於編譯器的,OP仍然不應該依賴這種行爲。我錯過了他如何調用'verify'的部分,儘管 – Attila 2012-03-26 22:32:33