2016-06-21 82 views
2

我剛剛開始用C語言編程,我正在使用代碼塊學習。我正在研究一個簡單的ATM程序,並決定在輸入無效條目時使用goto函數來使用。當我第一次使用它時,它按預期運行。但現在它不會超越其中一個陳述。代碼如下。卡在一個循環中

當按下任意選項1-3時,它按照假設運行,但也繼續運行後面的選擇錯誤部分。如果我只是試圖運行選擇錯誤部分,它會通過它並不斷重複它。我如何阻止這種情況發生?只有當條件滿足時,我才需要無效的選擇部分。謝謝!

int iSelection = 0; 

float fTransAmount = 0.0; 

float fBalance = 100.25; 

    printf("\n\n\tATM\n"); 

menu_options: 

    printf("\n1\t To Make a Deposit Press One"); 
    printf("\n2\t To Make a Withdrawal Press Two"); 
    printf("\n3\t To End Transaction, Press Three\n"); 
    scanf("%d", &iSelection); 

    if (iSelection == 1) { 
     printf("\n Enter Amount to Deposit: "); 
     scanf("%f", &fTransAmount); 
     printf("\n Your new balance is: $%.2f", fBalance + fTransAmount); 

    } //End if for 1 

    if (iSelection == 2) { 
     printf("\n Enter Amount to Withdraw: "); 
     scanf("%f", &fTransAmount); 

     if (fTransAmount > fBalance) 
      printf("\n Insufficient funds, ending transaction.....\n"); 
     else 
      printf("\n Your new balance is $%.2f\n", fBalance - fTransAmount); 

    } //End if for 2 

    if (iSelection == 3) { 
     printf("\n ending transaction"); 

    } //End if for 3 

     if (iSelection != 1 || iSelection != 2 || iSelection != 3 ) { 
     printf("\nInvalid selection, please try again"); 

     goto menu_options; 
    } //End if for Selection Error 
+2

不要使用'goto'。您可以將其重寫爲'while'循環,這樣可以更輕鬆地使用和調試。請參閱:http://stackoverflow.com/questions/46586/goto-still-considered-harmful。 –

+3

「if(iSelection!= 1 || iSelection!= 2 || iSelection!= 3)」的邏輯錯誤,應該是&&'。但是,甚至不要這樣做,在條件2和3中使用'else if',然後使用'else'。 –

+0

儘管CS專業人士說,goto非常適合在C語言中使用,但他們應該保持在可提高可讀性的位置。你的代碼不是一個好用例。其實它甚至不是一個可以接受的。使用其他迭代語句。 – Olaf

回答

0

if條件是錯誤的:

(iSelection != 1 || iSelection != 2 || iSelection != 3 ) 

iSelection不是1或不是2 OR不3.這將始終是真的這會成真。你不是想用一個邏輯AND(&&):

(iSelection != 1 && iSelection != 2 && iSelection != 3 ) 

此外,這是不恰當的使用goto。你最好使用while循環:

while(1) { 
    printf("\n1\t To Make a Deposit Press One"); 

    ... 

    if (iSelection != 1 && iSelection != 2 && iSelection != 3 ) { 
     printf("\nInvalid selection, please try again"); 
    } else { 
     break; 
    } 
} 

更重要的是,使用的不是多個ifswitch聲明:

do { 

    printf("\n1\t To Make a Deposit Press One"); 
    printf("\n2\t To Make a Withdrawal Press Two"); 
    printf("\n3\t To End Transaction, Press Three\n"); 
    scanf("%d", &iSelection); 

    int invalidSelection = 0; 
    switch (iSelection) { 
    case 1: 
     printf("\n Enter Amount to Deposit: "); 
     scanf("%f", &fTransAmount); 
     printf("\n Your new balance is: $%.2f", fBalance + fTransAmount); 
     break; 
    case 2: 
     printf("\n Enter Amount to Withdraw: "); 
     scanf("%f", &fTransAmount); 

     if (fTransAmount > fBalance) 
      printf("\n Insufficient funds, ending transaction.....\n"); 
     else 
      printf("\n Your new balance is $%.2f\n", fBalance - fTransAmount); 
     break; 
    case 3: 
     printf("\n ending transaction"); 
     break; 
    default: 
     printf("\nInvalid selection, please try again"); 
     invalidSelection = 1; 
     break; 
    } 
} while (invalidSelection); 
0

對於作爲循環回到起點失敗簡單的東西,您應該使用while(1)for(;;)循環不斷重複,直到執行語句break。它的可讀性更高,直線性更好。 goto在C中主要用於資源清理,因爲沒有對象或異常,處理錯誤條件和釋放內存可能很難。

說了這麼多,你的問題是if (iSelection != 1 || iSelection != 2 || iSelection != 3 )。您正在測試您的選擇不是1或者它不是2或者它不是3。這總是true,因爲它從來都不是三個同時。

你想:if (iSelection != 1 && iSelection != 2 && iSelection != 3 )

+0

你甚至不需要最後一條if語句: – FredK

+0

^同意,你可以在所有其他if語句中「斷開」以繼續循環,並且在沒有輸入這些語句的情況下,可以打印一條消息,然後在循環結束時,你會跳到頂部。在那張紙上,你可以使用'if' -'else'樹來考慮你所有的條件是相互排斥的。最後的條件是最後的'else'塊。 –

0

你甚至都不需要最終的if語句:

int repeat = 1; 
while (repeat) { 
    repeat = 0; 
    if (iSelection == 1) { 
     ... 
    } else if (iSelection == 2) { 
     ... 
    } else if (iSelection == 3) { 
     ... 
    } else { 
     // print error here 
     repeat = 1; 
    } 
} 

或者你也可以使用的switch-case結構。 這樣做的好處是,如果您爲iSelection添加其他有效值,則只需添加一個額外的「else if」塊而不需要編輯最終的if語句。