分享
三行代码  ›  专栏  ›  技术社区  ›  Chris Silver

C-扫描和打印不正常,我不知道为什么

  •  3
  • Chris Silver  · 技术社区  · 9 月前

    我有一个问题,我需要用C语言中的函数指针编写一个菜单驱动的程序。用户选择一个选项1-3,如果response=1执行加法,如果response=2执行减法,如果response=3执行乘法。

    第一次运行是完美的,但是一旦我循环并尝试进行第二次计算,它会在显示您所做的选择之前搜索选择和第一个数字。

    每个函数中的数学运算都有效,传递变量也有效,只有printf和scanf语句在第一次运行之后就不正常了。

    (有减法和乘法函数,它们完全相同,除了“+”运算符之外,还有“-”和“*”运算符。)

    我搜索了类似的问题,尝试了fflush和setvbuf命令,但这些命令不起作用。

    void addition(int num1, int num2);
    void subtraction(int num1, int num2);
    void multiplication(int num1, int num2);
    
    int main(void) {
        void(*m[3])(int, int) = { addition, subtraction, multiplication };
    
        size_t choice;
        int num1, num2;
        printf_s("Would like to add, subtract, or multiply?\nType 1 for 
    addition, 2 for subtraction, 3 for multiplication.\n");
        scanf_s("%d", &choice);
        printf_s("what two numbers would you like to work with?\n");
        scanf_s("%d", &num1);
        scanf_s("%d", &num2);
            if (choice >= 1 && choice <= 3) {
            (*m[choice - 1])(num1, num2);
            while (choice >= 1 && choice <= 3) {
    
                printf_s("Would like to add, subtract, or multiply?\nType 1 
    for addition, 2 for subtraction, 3 for multiplication.\n");
                choice = 0;
                scanf_s("%d\n", &choice);
                printf_s("what two numbers would you like to work with?\n");
                scanf_s("%d", &num1);
                scanf_s("%d", &num2);
                (*m[choice - 1])(num1, num2);
            }
            printf("execution complete");
        }
        return 0;
    }
    
    void addition(int num1, int num2) {
        int i = 0;
        i = num1 + num2;
        printf("%d + %d = %d\n", num1, num2, i);
        }
    

    如果我输入以下内容:1 2 3,2 3 1,我希望输出为

    "1"
    
    "What two numbers would you like to work with?"
    
    "2"
    
    "3" 
    "2+3=5" 
    "would you like to add, subtract, or multiply?" 
    "Type 1 (...) for multiplication" 
    "2" 
    "what two numbers (...)" 
    "3" 
    "1" 
    "3-1 =2"
    

    但是我得到了:

    "1" 
    "What two numbers would you like to work with?"
    "2" 
    "3" 
    "2+3=5" 
    "would you like to add, subtract, or multiply?" 
    "Type 1 (...) for multiplication"
    "2" 
    "3" 
    "what two numbers (...)" 
    "1" 
    "3-1 =2"
    

    正如你所看到的,数学是正确的,但是第二次它需要2个数字才能要求2个数字。我不明白这是怎么可能的,因为在执行下面的printf语句之前,只扫描了一个变量。即使我乘以的“3”保存在num1中,它在printf之前扫描,即使语句在printf之后,所以这不可能。我很困惑!

    4 回复  |  直到 9 月前
        1
  •  1
  •   chux    9 月前

    去除 '\n' .

    scanf_s("%d\n"... 只有在数字后输入非空白,才会返回。

    // scanf_s("%d\n", &choice);
    scanf_s("%d", &choice);
    

    其他问题也可能存在。

        2
  •  2
  •   bruno    9 月前

    为什么这么长这么复杂的代码?

    只是替换

    printf_s("Would like to add, subtract, or multiply?\nType 1 for addition, 2 for subtraction, 3 for multiplication.\n");
    scanf_s("%d", &choice);
    printf_s("what two numbers would you like to work with?\n");
    scanf_s("%d", &num1);
    scanf_s("%d", &num2);
        if (choice >= 1 && choice <= 3) {
        (*m[choice - 1])(num1, num2);
        while (choice >= 1 && choice <= 3) {
    
            printf_s("Would like to add, subtract, or multiply?\nType 1 for addition, 2 for subtraction, 3 for multiplication.\n");
            choice = 0;
            scanf_s("%d\n", &choice);
            printf_s("what two numbers would you like to work with?\n");
            scanf_s("%d", &num1);
            scanf_s("%d", &num2);
            (*m[choice - 1])(num1, num2);
        }
        printf("execution complete");
    }
    

    通过

    for (;;) {
      printf("Would like to add, subtract, or multiply?\nType 1 for addition, 2 for subtraction, 3 for multiplication.\n");
      if (scanf("%d", &choice) != 1) {
        puts("abort");
        break;
      }
    
      if ((choice < 1) || (choice > 3))
        break;
    
      printf("what two numbers would you like to work with?\n");
      if (scanf("%d %d", &num1, &num2) != 2) {
        puts("abort");
        break;
      }
      (*m[choice - 1])(num1, num2);
    }
    printf("execution complete");
    
        3
  •  2
  •   Adam    9 月前

    我会这样做:

    int main(void) {
        void(*m[3])(int, int) = { addition, subtraction, multiplication };
        size_t choice = 1;
        int num1, num2;
        while (choice >= 1 && choice <= 3) {
            printf_s("Would like to add, subtract, or multiply?\nType 1 for addition, 2 for subtraction, 3 for multiplication.\n");
            choice = 0;
            scanf_s("%d", &choice);
            printf_s("what two numbers would you like to work with?\n");
            scanf_s("%d", &num1);
            scanf_s("%d", &num2);
            (*m[choice - 1])(num1, num2);
        }
        return 0;
    }
    

    你的问题是-你有 scanf_s("%d\n", &choice); -您应该在没有\n- scanf_s("%d", &choice); 你可以做的更简单。 删除if并将choice设置为1。

        4
  •  0
  •   DDS    9 月前

    使用 scanf_s("%d\n",&var); 这样,您就“强制”scanf读取“提交”数据项时插入的新行(enter)字符。另一种情况是,该字符将在流中重新出现并影响下一次扫描,并且作为该字符的Enter,将使您的代码更进一步。