【问题标题】:While loop doesn't execute statements at each iterationWhile 循环不会在每次迭代时执行语句
【发布时间】:2021-04-01 18:16:47
【问题描述】:

我是 C 语言的初学者,遇到了一个大的 while 循环问题。基本上我在循环中有 2 个变量赋值,由于某种原因在每次迭代中都没有执行,所以变量的值保持不变。除此之外,一切正常。

编辑:我现在知道我设置为 double 的变量在 play() 函数中默认为 int。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

int play();

int main()
{
    double correct, attempts;
    char host[10], player[10];

    system("cls");

    printf("What's up strangers! Welcome to my game.\n");
    printf("Please CAREFULLY read all prompts from this point forward.\n");

    system("pause");
    system("cls");

    printf("First thigs first, HOST, what is your name? ");
    scanf("%s", host);

    system("cls");

    printf("Ok %s, what is the number you would like the player to guess? ", 
host);
    scanf("%d", &correct);
    printf("Then how many attempts would like them to have on guessing? ");
    scanf("%d", &attempts);
    printf("Thank you %s, now please leave room for our fearless player of 
the day.\n", host);

    system("pause");
    system("cls");

    printf("Mighty player, your fearless game host for today is %s. Please 
enter your name: ", host);
    scanf("%s", player);

    system("cls");

    printf("Alright %s! The rule is simple, you have %d attempts to guess 
%s's number.", player, attempts, host);
    printf("Any time you guess wrong, the game will tell you how far off your 
answer was.\n");
    printf("Your score will be displayed at he end of the game.\n");
    printf("Whenever you are ready... Good luck!");

    system("pause");
    return play(correct, attempts, host, player);
}

play(correct, attempts, host, player)
{
    double count = 1, pcent, pdiff, answer;
    char score[1], suffix[2];

    while (count < attempts)
    {
        pcent = 100*sqrt(pow((1-(count/attempts)), 2));
        if (pcent == 100)
        {
            strcpy(score, "S");
        }
        else if (pcent < 100 && pcent >= 90)
        {
            strcpy(score, "A");
        }
        else if (pcent < 90 && pcent >= 80)
        {
            strcpy(score, "B");
        }
        else if (pcent < 80 && pcent >= 70)
        {
            strcpy(score, "C");
        }
        else if (pcent < 70 && pcent >= 60)
        {
            strcpy(score, "D");
        }
        else
        {
            strcpy(score, "F");
        }

        if (count == 1)
        {
            strcpy(suffix, "st");
        }
        else if (count == 2)
        {
            strcpy(suffix, "nd");
        }
        else if (count == 3)
        {
            strcpy(suffix, "st");
        }
        else
        {
            strcpy(suffix, "th");
        }

        printf("%d", pcent);
        printf("%s, please enter your %d%s guess: ", player, count, suffix);
        scanf("%d", &answer);
        pdiff = 200*((answer-correct)/(answer+correct));
        printf("%f", pdiff);

        system("cls");

        if (answer == correct)
        {
            printf("That is correct %s! You got it on your %d%s try.\n", 
player, count, suffix);
            printf("Your score is %s.", score);
            system("pause");
            return main();
        }
        else
        {
            printf("Wrong answer %s! Your guess was %f percent off from the 
correct answer.\n", player, pdiff);
            printf("You have %d attempts remaining.\n", attempts-count);
            system("pause");
        }
        count ++;
    }
    printf("Sorry %s, but you have no more attempt remaining... Please play 
again later.\n", player);
    return main();
}

【问题讨论】:

  • 我的水晶球说删除while (stuff);之后的';'...欢迎来到Stack Overflow。请尽快阅读About 页面并访问描述How to Ask a QuestionHow to create a Minimal, Complete, and Verifiable example (MCVE) 的链接。提供必要的详细信息,包括您的 MCVE、编译器警告和相关错误(如果有),将允许这里的每个人帮助您解决您的问题。
  • char score[1], suffix[2]; 都是 1 字符太短,无法容纳您复制的字符串。您必须至少拥有char score[2], suffix[3];。建议两者都使用char score[8], suffix[8];,或者将score 设为char 而不是数组。

标签: c while-loop variable-assignment


【解决方案1】:

如果没有您的完整代码,就不可能 100% 确定我已经涵盖了所有内容,但我相信我已经掌握了明显的内容:

  • 您的主要数学问题似乎与pcent = 100*sqrt(pow((1-(count/attempts)), 2));pdiff = 200*((answer-correct)/(answer+correct)); 中出现的整数除法有关。如果您需要每个除法中的小数部分,请将除数(或除数)转换为 (double)
  • 您的数组太短了,无法保存您尝试strcpy() 的字符串。建议将score 设为char 并使用suffix[8]。 (最好是 10,000 个字符太长而不是一个字符太短)。
  • 始终为参数列表中的每个变量提供类型
  • 始终在每个switch() 情况下提供break; 语句(尽管您现在已经编辑了一个使用过的if .. else if .. else)。如果您未能break; 失败,则会发生下一个案例。
  • 你的函数类型是int,所以当你return时,你return value;其中value是类型int,而不是main()。您不需要返回调用函数,因为您的play() 函数已经将frame-pointer 存储为main() 作为函数序言 的一部分,并且知道在完成后将控制权返回到哪里。
  • 选择一个有意义的回报,例如return 1; 出错,return 0; 成功,C 为 EXIT_FALURE (1) 和 EXIT_SUCCESS (0) 提供了两个宏。
  • 通过检查返回来验证每个用户输入。
  • 通过检查返回来验证每次转化。
  • 使用大小合理的缓冲区(字符数组),并使用fgets() 而不是scanf() 获取所有用户输入,因此stdin 中未读的内容不取决于转换说明符或匹配发生故障
  • 使用 sscanf() 从缓冲区中获取(解析)单个值,就像使用 scanf() 但提供缓冲区作为第一个参数一样。
  • 您只需调用一次printf()(或puts()fputs())即可输出一个连续的文本块——不管它有多少行。
  • 仅在需要转换时使用printf(),否则如果您希望自动附加'\n',请使用puts(),如果您需要行尾控制——例如提示输入,请使用fputs()
  • "The expression of each case label shall be an integer constant expression..." C11 Standard - 6.8.4.2 The switch statement(p3) 您对范围表达式的使用,例如60 ... 69 仅由非标准编译器扩展提供。

可能还有更多我忘记提及的变化。我怀疑您的player 实际上是char*,但由于缺少类型,它在您的问题中默认为int。所以将下面printf()格式字符串中使用的%d改成%s,如果是这样的话。我在下面包含了更多的 cmets:

更新功能

#define MAXC 256        /* if you need a constant, #define one or more */

int play (int correct, int attempts, int host, int player)
{
    int count = 1, answer = 0;                          /* initialize variables */
    char buf[MAXC] = "", score = 0, suffix[8] = "";
    double pdiff = 0., pcent = 0.;

    while (count < attempts)
    {
        pcent = 100 * sqrt(pow((1-((double)count/attempts)), 2));
        switch ((int)pcent)
        {
            case 60 ... 69:
                score = 'D'; break;             /* you must break or fall-through occurs */
            case 70 ... 79:
                score = 'C'; break;
            case 80 ... 89:
                score = 'B'; break;
            case 90 ... 99:
                score = 'A'; break;
            case 100:
                score = 'F'; break;
            default:
                score = 'S'; break;
        }

        switch (count)
        {
            case 1:
                strcpy (suffix, "st"); break;   /* ditto */
            case 2:
                strcpy (suffix, "nd"); break;
            case 3:
                strcpy (suffix, "rd"); break;
            default:
                strcpy (suffix, "th"); break;
        }

        printf ("percent: %.2f\n", pcent);          /* left alone since it looks like debug */
        printf ("%d, please enter your %d%s guess: ", player, count, suffix);
        
        if (!fgets (buf, MAXC, stdin)) {            /* read & VALIDATE all user-input */
            puts ("(user canceled)");
            return 1;
        }
        
        if (sscanf (buf, "%d", &answer) != 1) {     /* validate EVERY conversion */
            fputs ("error: invalid integer input.\n", stderr);
            return 1;
        }
        pdiff = 200 * ((double)(answer-correct) / (answer+correct));
        printf ("%f", pdiff);

        // system("cls");           /* not really needed, just scrolls lines up */

        if (answer == correct)
        {
            printf ("That is correct %d! You got it on your %d%s try.\nYour score is %c.",
                    player, count, suffix, score);
            // system("pause");
            fgets (buf, MAXC, stdin);       /* will do nicely instead of pause */
            return 1;                       /* just return */
        }
        else
        {
            printf ("Wrong answer %d! "
                    "Your guess was %.2f percent off from the correct answer.\n"
                    "You have %d attempts remaining.\n", player, pdiff, attempts-count);
            // system("pause");
            fgets (buf, MAXC, stdin);       /* will do nicely instead of pause */
        }
        count++;
    }
    printf ("Sorry %d, but you have no more attempt remaining... "
            "Please play again later.\n", player);

    return 0;     /*just return -- the function handles saving the callers */
}

这是我对您需要的最佳猜测。根据需要调整player 的类型。

【讨论】:

    【解决方案2】:

    wismus2999,

    我相信如果变量是整数类型,你可能不会修改它们,一个例子是:

    while (<condition>) {
       a = 2;
    }
    

    上面的代码与此不同:

    while (<condition>) {
       a++;
       // or a = a + 1;
    }
    

    由于没有代码或照片可以分析,因此很难给出 具体答案。

    【讨论】:

    • 我想我把上面的代码贴出来了,你看不到吗? (如果没有,我会尝试重新发布)并且我不太理解您的答案,我在循环之前将计数变量声明为 int count = 1 然后在最后放置一个 count++ 。提前致谢!
    最近更新 更多