为什么我的 do-while 循环在一次迭代后退出?

Why does my do-while loop exit after one iteration?

提问人:Summer 提问时间:9/13/2023 最后编辑:chqrlieSummer 更新时间:9/20/2023 访问量:123

问:

初学者程序员在这里:

我正在尝试格式化循环,以便如果用户输入了 0-4 范围之外的错误数字,那么我的程序应该要求用户输入正确范围内的数字。满足该参数后,我希望我的代码继续运行语句。我错过了什么?dowhileif

#include <stdio.h>

int main() {

    int userNum;
    char tableOne[5] = { 'A', 'B', 'C', 'D', 'E' };
    int tableTwo[5] = { 11, 12, 13, 14, 15 };

    printf("Enter a whole number in the range of 0 to 4.\n");
    scanf("%d", &userNum);

    do {
        printf("ERROR. ENTER WHOLE NUMBER \nIN THE RANGE OF 0 - 4 \nIN NUMERICAL FORMAT.\n");
        scanf("%d", &userNum);
        break:
    } while (userNum < 0 || userNum > 4);

    if (userNum == 0) {
        printf("%d", tableOne[0] + tableTwo[0]);
    }
    if (userNum == 1) {
        printf("%d", tableOne[1] + tableTwo[1]);
    }
    if (userNum == 2) {
        printf("%d", tableOne[2] + tableTwo[2]);
    }
    if (userNum == 3) {
        printf("%d", tableOne[3] + tableTwo[3]);
    }
    if (userNum == 4) {
        printf("%d", tableOne[4] + tableTwo[4]);
    }
    return 0;
}
数组 C 循环 do-while

评论

1赞 luther 9/13/2023
idownvotedbecau.se/imageofcode
1赞 Some programmer dude 9/13/2023
为什么我不应该上传代码/数据/错误的图像?请花一些时间阅读帮助页面,参加 SO 导览,阅读如何提问,以及如何编写“完美”问题,尤其是其清单。然后编辑您的问题以改进它。
1赞 Some programmer dude 9/13/2023
我建议您将整行作为文本阅读(例如)。然后使用 or 将其转换为数字,并进行验证。如果使用 ,请记住检查它返回的内容。这样可以更容易地丢弃非数字输入,而您当前的系统存在问题。fgetssscanfstrtolsscanf
0赞 Lundin 9/13/2023
break:这真的编译了吗?请使用复制/粘贴来发布实际代码。

答:

2赞 0___________ 9/13/2023 #1
  1. break语句后立即退出循环,它甚至没有达到条件检查。删除它scanfwhile

  2. 检查结果以查看数字是否被正确读取:scanf

    if(scanf ("%d", &userNum) != 1) {/* do something as user input was incorrect */}
    
  3. 你也不需要这些(也不需要 - 你应该在你的练习册上阅读或问你的老师这句话是做什么的):ifbreak

    printf("%d", tableOne [userNum] + tableTwo [userNum]);
    
-3赞 Nyanyaitaly 9/13/2023 #2

我认为你需要这样的东西。您需要将 {} 放在 while 循环中。

#include <stdio.h>

int main() {

int userNum;

char tableOne [5] = {'A', 'B', 'C', 'D', 'E'};

int tableTwo [5] = {11, 12, 13, 14, 15};

printf ("Enter a whole number in the range of 0 to 4.\n");

do {
 scanf("%d", &userNum);
 printf("ERROR. ENTER WHOLE NUMBER \nIN THE RANGE OF 0-4 \nIN NUMERICAL FORMAT.\n");     scanf("%d", &userNum);
}
while (userNum < 0 || userNum > 4){

if (userNum == 0){ 
    printf("%d", tableOne [0] + tableTwo [0]); 
    break;
}

if (userNum == 1){ 
    printf("%d", tableOne [1] + tableTwo [1]);
    break;
}

if (userNum == 2){ 
    printf("%d", tableOne [2] + tableTwo [2]);
    break;
}

if (userNum == 3){ 
    printf("%d", tableOne [3] + tableTwo [3]);
    break;
}

if (userNum == 4){
    printf("%d", tableOne [4] + tableTwo [4]);
    break;
}

return 0;
 }
}

编辑

所以,现在我知道你的do while循环有一些问题。 因为打印 printf 并且没有执行 if' 语句。 我会搜索一些东西来提供一些像样的代码。

试试这个:

#include <stdio.h>

 int main() {

 int userNum;

char tableOne [5] = {'A', 'B', 'C', 'D', 'E'};

int tableTwo [5] = {11, 12, 13, 14, 15};

printf ("Enter a whole number in the range of 0 to 4.\n");
scanf("%d", &userNum);

if (userNum < 0 || userNum > 4){
  do {
   printf("ERROR. ENTER WHOLE NUMBER IN THE RANGE OF 0-4 \nIN NUMERICAL FORMAT.\n");     
   scanf("%d", &userNum);
  }
  while (userNum < 0 || userNum > 4);
}

if (userNum == 0){ 
    printf("%d", tableOne [0] ); 
}

if (userNum == 1){ 
    printf("%d", tableOne [1] + tableTwo [1]);
}

if (userNum == 2){ 
    printf("%d", tableOne [2] + tableTwo [2]);
}

if (userNum == 3){ 
    printf("%d", tableOne [3] + tableTwo [3]);
}

if (userNum == 4){
    printf("%d", tableOne [4] + tableTwo [4]);
}

return 0;
 

}

评论

1赞 Some programmer dude 9/13/2023
此代码与问题中图像中的代码有什么区别?它有什么区别?为什么它能解决OP的问题?请阅读有关如何写出好答案的信息
0赞 Some programmer dude 9/13/2023
哦,现在我明白你做了什么。这是错误的,并且会导致生成错误。你似乎误解了 OP 的代码。而且你似乎对 C 中的循环语句有一个基本的误解。
0赞 Nyanyaitaly 9/13/2023
现在你让我看到了。我会编辑并考虑更多。谢谢你的信息
1赞 chqrlie 9/13/2023 #3

该语句在 之后立即退出循环。这解释了您的观察结果:循环在 1 次迭代后退出。它实际上在第一次迭代期间退出,在验证测试之前。breakscanf()

请注意,您应该检查转换错误,使用有问题的输入,并在没有返回的情况下重新启动输入,如果没有更多可用的输入,则报告文件末尾。scanf()1

循环不适合将两种形式的输入验证结合起来,因为如果存在转换错误,则有效性测试毫无意义,并且无法用语句绕过它。 循环很少是正确的工具,并且往往会嵌入逻辑错误,例如缺少条件。您应该使用循环(又名 for ever 循环)并显式编写条件。do { ... } whilecontinuedo { ... } whilefor (;;)

结合使用 and instead 可以更好地处理和恢复错误。fgets()sscanf()scanf()

这是修改后的版本:

#include <stdio.h>

int main(void) {

    int userNum;
    char tableOne[5] = { 'A', 'B', 'C', 'D', 'E' };
    int tableTwo[5] = { 11, 12, 13, 14, 15 };

    for (;; printf("Try again: ")) {
        char buf[80];
        int offset = 0;

        printf("Enter a whole number in the range of 0 to 4: ");

        // read input from the user
        if (!fgets(buf, sizeof buf, stdin)) {
            printf("Missing input: unexpected end of file. Aborting.\n");
            return 1;
        }
        // attempt to convert the input as an integer
        if (sscanf(buf, "%d %n", &userNum, &offset) != 1) {
            printf("Invalid input: not a number.\n");
            continue;
        }
        if (userNum >= 0 && userNum <= 4) {
            // value is invalid
            printf("Error: value must be in range 0 to 4: %d.\n", userNum);
            continue;
        }
        // input was successful and value is correct, check for extra input
        if (buf[offset] != '\0') {
            // this should be considered an error, for example if the user
            // typed 1.2, the extra input ".2" is definitely an error.
            printf("Extra characters: %s\n", buf + offset);
            continue;
        }
        // input was successful and value is in the expected range.
        break;
    }

    // note that the code below can be replaced with a single statement
    // printf("%d\n", tableOne[userNum] + tableTwo[userNum]);

    if (userNum == 0) {
        printf("%d\n", tableOne[0] + tableTwo[0]);
    }
    if (userNum == 1) {
        printf("%d\n", tableOne[1] + tableTwo[1]);
    }
    if (userNum == 2) {
        printf("%d\n", tableOne[2] + tableTwo[2]);
    }
    if (userNum == 3) {
        printf("%d\n", tableOne[3] + tableTwo[3]);
    }
    if (userNum == 4) {
        printf("%d\n", tableOne[4] + tableTwo[4]);
    }
    return 0;
}