C-Scanf和Printf执行不正常,I';我不知道为什么

C-Scanf和Printf执行不正常,I';我不知道为什么,c,function,pointers,printf,scanf,C,Function,Pointers,Printf,Scanf,我有一个问题,我需要使用C中的函数指针编写一个菜单驱动程序。用户选择一个选项1-3,如果响应=1,则执行加法;如果响应=2,则执行减法;如果响应=3,则执行乘法 第一次运行是完美的,但一旦我循环并尝试进行第二次计算,它将搜索选项和第一个数字,然后显示您所做的选择 每个函数中的数学都起作用,传递变量也起作用,只是printf和scanf语句在第一次运行后出现错误 (有减法和乘法函数,它们完全相同,只是分别有“-”和“*”运算符而不是“+”运算符。) 我搜索了一个与此类似的问题,并尝试了fflush

我有一个问题,我需要使用C中的函数指针编写一个菜单驱动程序。用户选择一个选项1-3,如果响应=1,则执行加法;如果响应=2,则执行减法;如果响应=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" 
"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之后,所以这应该是不可能的。我太糊涂了

使用
扫描(“%d\n”和&var)这样做可以“强制”scanf读取“提交”数据输入时插入的新行(enter)字符。否则,该字符将在流中重新出现并影响下一次扫描,并且作为输入字符,将使您的代码更进一步。

为什么代码如此长且复杂

替换

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");
}
printf_s(“要加、减或乘?\n加1,减2,乘3”);
scanf_s(“%d”和选项);
printf_s(“您希望使用哪两个数字?\n”);
扫描单位(“%d”和num1);
扫描单位(“%d”和num2);
如果(选项>=1&&choice=1&&choice 3))
打破
printf(“您希望使用哪两个数字?\n”);
如果(扫描频率(“%d%d”、&num1和&num2)!=2){
出售(“中止”);
打破
}
(*m[choice-1])(num1,num2);
}
printf(“执行完成”);

删除
'\n'

scanf_s(“%d\n”…
将不会返回,直到在数字后输入非空格

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

其他问题也可能存在。

我会这样做:

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;
}
int main(无效){
void(*m[3])(int,int)={加、减、乘};
尺寸选择=1;
int num1,num2;

(选择>=1 & &选择考虑在问题(代码和散文)中使用一些换行符/换行符,以提高可读性;尤其是在预期输出中。<代码> SsieZyt选择;SnffIs(“%d”,和选择);<代码> int选择;< /code >。删除额外的<代码> \n“/code”在一个扫描程序中……这一个代码>代码Snffs(“%d\n”)。
您从不检查
scanf_s()
的返回值,因此您永远不知道它的读数。还要注意的是,像
scanf_s()
这样的所谓“安全”函数并不比所谓的“不安全”函数更安全(它们不是“不推荐的”-它们是C标准所要求的…)您真正使用它们所做的一切就是使您的代码不可移植且特定于平台。@AndrewHenle这就是为什么我刚刚编辑了我的答案;-)谢谢您,我查看了那一行很多次,但多余的\n都没有点击。祝您玩得愉快。如何选择解决几乎什么问题的答案?“其他问题也可能存在”英雄联盟sure@bruno代码有很多缺点。我知道至少有5个。如果OP想要一个全面的评论,这是一个很好的地方。@bruno是的。有了chux的回答,我意识到了我的错误,并且能够解决它,你只需编写自己的代码,我就永远不会知道这个问题。是的,我知道了,修复了。
// scanf_s("%d\n", &choice);
scanf_s("%d", &choice);
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;
}