2016-09-11 70 views
1

因此,我正在为我的C程序使用视觉工作室。在while循环中使用“continue”,跳过scanf(“%d”,var)

while循环以提示符和scanf开头,如果用户输入非数字响应,则循环中的开关/情况将变为默认值。这会打印一个错误并“继续”循环。

问题是,当循环继续下一次迭代时,它会完全跳过“scanf”,然后通过默认情况无限循环。我搜索了几个小时,但似乎无法找到解决方案。

我的目标是跳过开关/大小写后的代码,然后回到开头。任何帮助将非常感激。

while (userInput != 'N' && userInput != 'n') { 

    printf("Enter input coefficients a, b and c: "); // prompt user input 
    scanf_s("%d %d %d", &a, &b, &c); // look for and store user input 

    /* ----- Break up the quadratic formula into parts -----*/ 

    inSqRoot = (pow(b, 2) - (4.0 * a * c)); // b^2 - 4ac 
    absInSqRoot = abs((pow(b, 2) - (4.0 * a * c))); // absolute value of b^2 - 4ac 
    denom = 2.0 * a; // get denomiator 2.0 * a 
    negB = -1.0 * b; // take negative of b 

    /*------ Determine number of roots -------*/ 

    if (!isdigit(a) || !isdigit(b) || !isdigit(c)) { 

     rootNum = 4; 

    } // end if 

    else if (a == 0 && b == 0 && c == 0) { 

     rootNum = 0; 
    } // end if 

    else if (inSqRoot == 0) { 

     rootNum = 1; 
    } // end if 

    else if (inSqRoot > 0) { 

     rootNum = 2; 
    } // end if 

    else if (inSqRoot < 0) { 

     rootNum = 3; 

    } // end if 


    /*------ Begin switch case for rootNum ------*/ 

    switch (rootNum) { 

    case 0: // no roots 

     printf("The equation has no roots.\n"); 
     break; 

    case 1: // one root 

     root1 = (-b + sqrt(inSqRoot))/denom; 

     printf("The equation has one real root.\n"); 
     printf("The root is: %.4g\n", root1); 
     break; 

    case 2: // two roots 

     root1 = (-b + sqrt(inSqRoot))/denom; 
     root2 = (-b - sqrt(inSqRoot))/denom; 

     printf("The equation has two real roots.\n"); 
     printf("The roots are: %.4g and %.4g\n", root1, root2); 
     break; 

    case 3: // imaginary roots 

     printf("The equation has imaginary roots.\n"); 
     printf("The roots are: %.1g + %.4gi and %.1g - %.4gi \n", negB/denom, sqrt(absInSqRoot)/denom, negB/denom, sqrt(absInSqRoot)/denom); 
     break; 

    default: 
     printf("ERROR: The given values are not valid for a quadratic equation.\n"); 
     continue; 
    } 

    printf("Enter Y if you want to continue or N to stop the program: "); 
    scanf_s("%*c%c", &userInput); 
    printf("\n"); 
} 
+1

“继续”表示“断开当前执行并从开始启动循环代码”。所以它是循环的“短路”。另一方面,'break'将退出循环块。在这里,你可以简单地跳过'conitinue',你的scanf_s将被执行。 – Antoniossss

+0

然而'case' statemets,'break'打破当前case'不是外部循环 – Antoniossss

+0

那么我的目标是跳过开关案例后的代码,如果默认情况下被激活。然后回到顶部并要求用户重新输入整数值。 – Abbie

回答

2

scanf实际上没有被跳过,它只是反复读取相同的错误输入。您可以使用scanf的返回值来查看读取了多少个参数。在恶劣输入的情况下,这将是小于3要刷新错误的输入,你可以这样调用

void flushInput() { 
    int c; 
    while ((c = getchar()) != '\n' && c != EOF); 
} 

的函数,在默认情况下添加到flushInput通话

default: 
    printf("ERROR: The given values are not valid for a quadratic equation.\n"); 
    flushInput(); 
    continue; 
+0

啊,你打败了我!上面我正在等她回答我的评论。我没有运行代码,但如果我是一个投注人,我会提供很好的赔率,你的回答是正确的。如果操作任务显示她反复看到“输入系数a,b和c:”,我就赞成你的答案! –

0

在涉及用户输入时,通常阅读和验证用户输入对编写一个行为良好的应用程序至关重要。用户可能会提交不完美的输入,并且您的应用程序应该检查它。

scanf()的未必是最好的选择,因为它是一个蒸汽输入,而不是控制台输入功能,不行为以预期的方式:

  • 将空白和换行符相同
  • 只会返回如果所有变量都被读取和分配,或遇到文件结束符(Ctrl + Z)。

所以我的建议是使用选择的控制台I/0函数来代替,这是gets()(或它的“安全”的形式gets_s())。这一行为与所需的行为相同,因为它完全读取整行文本,并在按下Enter键时返回(scanf()甚至可能从下一行读取参数)。

然后使用sscanf(),它就像scanf(),但是从缓冲区中读取变量,并返回读取和分配的变量数量。您可以使用“%d%d & d%s”作为格式字符串,以检查用户是否输入了正好3个变量,而不是更少或甚至更多(第四个变量将是一个虚拟字符串,使用只有当用户提交乱码输入时sscanf()才会返回3以上)。