【问题标题】:simple loop code in CC中的简单循环代码
【发布时间】:2015-10-20 20:34:34
【问题描述】:

这个程序中的循环没有像我预期的那样工作:

int main() {
    char userresponse;
    char x;

    do {
        printf("are you human");
        scanf("%c", &userresponse);
        if (userresponse == 'y') {
            printf("welcome");
        }
        if (userresponse == 'y') {
            printf("please leave");
        }
        printf("type z to repeat");
        scanf("%c", &x);
    } while (x == 'z');

    return 0;
}

它进入“type z to repeat”,然后结束。当我尝试定义char x='z'; 时,程序第一次运行良好,但最后它循环了2 或4 次,在if 语句中显示所有printf 消息,甚至是else 消息。

我希望程序在循环底部等待输入,然后根据该输入跳出循环或继续循环。为什么不这样做?

【问题讨论】:

  • 请修正缩进。没有缩进让代码难以理解。
  • 欢迎来到 Stack Overflow。请尽快阅读About 页面。在这里展示代码时,请以适度正统的风格缩进。把它放在编辑框中你想要的样子(忽略预览),然后选择代码并使用编辑框上方的 {} 按钮将其缩进四个空格,这使它显示为代码。如果缩进,您的代码将更容易理解。正如最初呈现的那样,它几乎是不可思议的。不要忘记在非提示输出的末尾添加一个换行符(并且在提示的输出末尾添加一个空格)。
  • 当您按yenter 作为输入时.. 它会在您的程序中输入 2 个字符。您将获得第一个 y.. 但接下来还有 \n。您可以通过使用 scanf("%c%*c",&x) 强制它忽略新行来修复
  • "even the else ones":你的程序中没有elses。有 2 个相同的 ifs 会产生看似相反的结果。
  • 最简单的解决方法是使用" %c"读取字符;它将忽略空格,包括换行符,并处理下一个不是空格的字符。

标签: c loops while-loop


【解决方案1】:
  1. 如果输入一个字符,就会隐式输入另一个字符:换行符,这部分会导致奇怪的行为。这可以通过将格式字符串"%c" 替换为"%c%*c" 来忽略。

  2. 您检查了两次'y'。将第二个'y' 替换为'n'

  3. 不影响程序的操作,但可能会提高性能:将第二个 if 替换为 else if。如果第一个计算结果为真,这将使程序甚至不测试第二个if 子句的条件。

  4. 您不会检查除yn 之外的其他字符。要么添加一个单独的else,或者代替我的第 3 点,将第二个 if 替换为 else1


1 正如@JonathanLeffler 在 cmets 中提到的那样

【讨论】:

  • 最好用!=替换第二个==,或者用else替换第二个if
  • @JonathanLeffler 完成。
【解决方案2】:

当您为userresponse 输入y 时,您可能必须在那之后点击Enter,对吧?

Enter 算作一个字符!由于它没有存储在userresponse 中,因此它保留在输入缓冲区中。从输入缓冲区读取的下一行是scanf("%c",&x);。所以你最终会在x 变量中得到一个Enter

接下来,您描述了程序显示所有 printf 消息,甚至是 else 消息,”
您在程序中看到关键字 else ?(因为我没有)

【讨论】:

    【解决方案3】:

    但最后它会循环 2 或 4 次,显示所有 printf 消息,

    有几种方法可以避免这种情况,一种是在scanf之后添加:

    while((check=getchar()) != EOF && check != '\n');
    

    最小的代码看起来像这样:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void){
        char a;
        int check,ok=0;
    
        do {
            printf("Give an A: ");
    
            if ((scanf("%c",&a)) == 1){
                while((check=getchar()) != EOF && check != '\n');
    
                if ((a == 'a') || (a == 'A')){
                    printf("True\n");
                    ok=0;
                } else {
                    printf("False\n");
                    ok = 1;
                }
            }else{
                printf("Error");
                exit(1);
            }
    
        }while (ok == 1);
    
        return 0;
    }
    

    但是按照您的处理方式,修复程序可能如下所示:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void){
        char userresponse;
        int check,ok=0;
        char x;
    
        do {
            printf("are you human:  ");
    
            if ((scanf("%c",&userresponse)) == 1){
                while((check=getchar()) != EOF && check != '\n');
    
                if ((userresponse == 'y') || (userresponse == 'Y')){
                    printf("welcome\n");
                    break;
                } else {
                    printf("please leave\n\n");
                    printf("type z to repeat");
                    if(scanf("%c",&x) == 1){
                        while((check=getchar()) != EOF && check != '\n');
                        if(x=='z' || x == 'Z'){
                            ok = 1;
                        }else{
                            printf("\n");
                            printf("Wrong Input\nGoodBye\n");
                            break;
                        }
                    }else{
                        break;
                    }
                }
            }else{
                printf("Error");
                exit(1);
            }
    
        }while (ok == 1);
    
        return 0;
    }
    

    我在这里要解释的是,没有理由坚持使用 x=='z' 这样的条件,只需使用上面示例中的另一个变量即可。

    试试看吧。

    编辑:

    如果您需要从代码开始,这里有一个快速解决方法:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void) {
        char userresponse;
        char x;
    
        do {
            printf("are you human");
            if(scanf(" %c", &userresponse) ==1){
                if (userresponse == 'y' || userresponse == 'Y') {
                    printf("welcome\n");
                }
                printf("type z to repeat\n");
                if(scanf(" %c", &x) != 1){
                    printf("Error");
                    exit(1);
                }
            }else{
                printf("Error");
                exit(1);
            }
    
        } while (x == 'z' || x == 'Z');
    
        return 0;
    }
    

    如您所见,我尽量避免遇到您的问题。 1) 我检查 scanf 是否有错误

    2) 我在 %c 前面放了一个空格以避免'\n'。

    3) 我检查 y 和 Y 以及 z 和 Z。

    【讨论】:

      【解决方案4】:

      这很好用:

      int main()
      {
        char userresponse;
        char x;
      
        do
        {
          printf("are you human");
          scanf(" %c", &userresponse);
      
          if (userresponse == 'y')
              printf("welcome\n");
          else
              printf("please leave\n");
      
          printf("type z to repeat");
          scanf(" %c", &x);
        }
        while (x == 'z');
      
        return 0;
      }
      

      【讨论】:

      • 你不检查 scanf 如果用户按 Y 而不是 y 会发生什么?
      • 在我非常非常谦虚的意见中,第一步是获取非工作代码并使其工作。然后可以改进。在这个过程中人们学习。只要一个因为不运行而被卡住,什么都不会发生。我倾向于只修复使其运行所需的内容。否则我需要解释太多,更迷惑人。
      • 我同意你的观点,但如果我们给出答案,那么我们至少应该解决这个问题,或者至少我们可以通知 OP。不是吗:)?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      相关资源
      最近更新 更多