簡體   English   中英

我的代碼在 C 中的 while() 循環的每次迭代中不斷跳過一部分

[英]My code keeps skipping a part every iteration of a while() loop in C

在我的循環的第一次迭代之后,它變得一團糟。

代碼如下:

#include <stdio.h>

int main()
{

    double a, b; char op = 'a';

    while(op != 'E')
    {
        printf("Insert operator: \n");
        scanf("%c", &op);

        printf("Insert first number: \n");
        scanf("%lf", &a);

        printf("Insert second number: \n");
        scanf("%lf", &b);

        switch(op)
        {
            case '+': printf("%lf \n", (a + b)); break;

            case '-': printf("%lf \n", (a - b)); break;

            case '*': printf("%lf \n", (a * b)); break;

            case '/': printf("%lf \n", (a / b)); break;
        }

        op = 'a';


    }

    return 0;
}

控制台如圖所示。 1

成績單:

Insert operator:
+
Insert first number:
1
Insert second number:
2
3.000000
Insert operator:
Insert first number:
8
Insert second number:
-
Insert operator:
Insert first number:
2
Insert second number:
5

我是編碼新手,這是我第一次使用 Stack Overflow,如果我做錯了諸如格式化問題之類的問題,我很抱歉。 感謝您的幫助!

您有兩個(實際上是 3 個)主要問題:

  1. 在用戶輸入b后按Enter后,您無法刪除stdin留下的'\\n' ,然后再嘗試再次讀取op "%c"格式說明(連同"%[...]" )不忽略空白,所以你必須手動添加space的前" %c"scanf()格式字符串,這樣的空白將被忽略;
  2. 您對op = 'a'; switch()語句之后確保op永遠不等於'E'用於退出while(op != 'E')循環。 您應該在op被讀取后測試op == 'E'是否並在用戶輸入'E'中斷循環。 (這也意味着您的循環可以簡單地為while(1)
  3. 最大的。 您未能檢查任何用戶輸入函數scanf() 如果不檢查 return ,則無法正確使用任何輸入函數(尤其是scanf() )。 您必須至少處理 3 種情況,1 - 良好的輸入,2 -匹配輸入失敗,以及 3 - EOF 如果你沒有檢查返回,您邀請所有類型的像未定義行為討厭的結果,當你試圖輸入失敗或者匹配發生故障無限循環,字符提取從輸入流停止后訪問變量的值,有問題的字符保留在您的輸入流中unread

要處理讀取和驗證op ,您可以執行以下操作:

#include <stdio.h>

int main (void) {

    double a, b; char op = 'a';

    while (1) {
        /* read and VALIDATE operator */
        fputs ("\nInsert operator (+,-,*,/) : ", stdout);
        if (scanf (" %c", &op) != 1 || op == 'E')
            return 1;
        /* validate op is one of + - * / */
        if (op != '+' && op != '-' && op != '*' && op != '/') {
            fputs ("error: invalid operator.\n", stderr);
            return 1;
        }

然后對於每個ab ,您可以執行以下操作:

        /* read and VALIDATE first number */
        fputs ("Insert first number       : ", stdout);
        if (scanf ("%lf", &a) != 1)
            return 1;
        /* read and VALIDATE second number */
        fputs ("Insert second number      : ", stdout);
        if (scanf ("%lf", &b) != 1)
            return 1;

注意:這些是所需的最低限度的驗證,它們不適應任何失敗和恢復,它們只是檢查輸入是否有效或退出)

總而言之,您可以執行類似於以下操作:

#include <stdio.h>

int main (void) {

    double a, b; char op = 'a';

    while (1) {
        /* read and VALIDATE operator */
        fputs ("\nInsert operator (+,-,*,/) : ", stdout);
        if (scanf (" %c", &op) != 1 || op == 'E')
            return 1;
        /* validate op is one of + - * / */
        if (op != '+' && op != '-' && op != '*' && op != '/') {
            fputs ("error: invalid operator.\n", stderr);
            return 1;
        }

        /* read and VALIDATE first number */
        fputs ("Insert first number       : ", stdout);
        if (scanf ("%lf", &a) != 1)
            return 1;
        /* read and VALIDATE second number */
        fputs ("Insert second number      : ", stdout);
        if (scanf ("%lf", &b) != 1)
            return 1;

        switch(op) {
            case '+': printf ("\n  %g + %g = %g\n", a, b, (a + b)); break;
            case '-': printf ("\n  %g - %g = %g\n", a, b, (a - b)); break;
            case '*': printf ("\n  %g * %g = %g\n", a, b, (a * b)); break;
            case '/': printf ("\n  %g / %g = %g\n", a, b, (a / b)); break;
        }
    }
}

示例使用/輸出

$ ./bin/scanf_char

Insert operator (+,-,*,/) : +
Insert first number       : 4
Insert second number      : 5

  4 + 5 = 9

Insert operator (+,-,*,/) : -
Insert first number       : 4
Insert second number      : 5

  4 - 5 = -1

Insert operator (+,-,*,/) : *
Insert first number       : 4
Insert second number      : 5

  4 * 5 = 20

Insert operator (+,-,*,/) : /
Insert first number       : 4
Insert second number      : 5

  4 / 5 = 0.8

Insert operator (+,-,*,/) : E

仔細檢查一下,如果您還有其他問題,請告訴我。

您的代碼不是跳過運算符,而只是在第二次 while 循環迭代中接收\\n ,在“第二個數字”之后輸入,在第一次循環迭代中。 您需要在運算符之前跳過所有\\n\\r字符。 例如,您可以通過在 sscanf(op) 周圍添加 do/while 來實現,例如:

 10         printf("Insert operator: \n");
 11         do
 12             scanf("%c", &op);
 13         while(op <  040);

或者,更好的解決方案:

  1 #include <stdio.h>
  2 
  3 int main()
  4 {
  5     double a, b; char op;
  6     for( ; ; )
  7     {
  8         printf("Insert operator[+-*/], a, b: ");
  9         fflush(stdout);
 10         char buf[100];
 11         fgets(buf, sizeof(buf), stdin);
 12         sscanf(buf, "%c%lf%lf", &op, &a, &b);
 13 
 14         switch(op)
 15         {
 16             case '+': printf("%lf \n", (a + b)); break;
 17             case '-': printf("%lf \n", (a - b)); break;
 18             case '*': printf("%lf \n", (a * b)); break;
 19             case '/': printf("%lf \n", (a / b)); break;
 20             case 'E': return 0;
 21         }
 22     }
 23 }       

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM