2016-06-21 87 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语句。