【问题标题】:Can someone explain this output? [duplicate]有人可以解释这个输出吗? [复制]
【发布时间】:2013-07-14 06:29:40
【问题描述】:

当我遇到这个时,我正在执行一些程序。

#include<stdio.h>
void main()
{
char z;
do
{
    printf("1st line\n");
    printf("2nd line\n");
            scanf("%c",&z);

    switch(z)
    {
        case 'a':printf("this is case a\n");
            break;
        case 'b':printf("this is case b\n");
            break;
        case 'c':printf("Exit\n");
            return;
            break;
        default:
            printf("this is default\n");
            break;
    }
}while(1);

}

我第一次输入时,输出是正确的。但是在给出第一个输入并且第二次循环开始之后, scanf 语句根本不会执行。 printf 语句虽然被执行,但也是默认情况。

第一行
第二行
b
这是案例b
第一行
第二行
这是默认的
第一行
第二行

【问题讨论】:

    标签: c scanf undefined-behavior


    【解决方案1】:

    当您在第一个 scanf 呼叫中输入 b 时,您还点击了 。当scanf("%c", &amp;z) 处理这个输入时,它在输入流中留下了换行符。

    第二组输出是由于scanf 读取了b 后面的换行符。由于\n 既不是a,也不是b,也不是c,它符合默认情况。

    您可以通过修改 scanf 字符串来修复行为,使其更符合您的预期:

    scanf(" %c", &z);
    

    注意%c 之前的空格字符。这将导致scanf 在处理输入之前跳过空白字符(包括换行符)。

    【讨论】:

      【解决方案2】:
      1. int main().

      2. 这里没有未定义的行为。只是scanf() 不像你想象的那样工作。 %c 消耗一个字符。 一个字符。 一个。并且它不会消耗您按 Enter 后留在stdin 缓冲区中的换行符。 (所以“第二个 scanf 没有执行”是不正确的 - 它已执行并处理剩下的任何内容。)现在,换行符不是 a、b 或 c 之一,所以 switch 语句在default: 标签处继续执行。


      如果你想从标准输入中读取一个字符,一个可靠的方法是:

      char buf[LINE_MAX];
      fgets(buf, sizeof buf, stdin);
      switch (buf[0]) {
          // etc.
      }
      

      替代方案:

      int c = fgetc(stdin);
      while (fgetc(stdin) == '\n')
          ;
      

      不要使用scanf()。 (至少在你理解它的作用之前不会。)它是邪恶的。

      【讨论】:

      • +1,我同意一般应避免使用scanf()
      • @H2CO3,我用 Eclipse 和 gcc 测试了这个示例,它的行为符合 OP 的预期。这是否意味着 Eclipse 不会将 \n 放入流中?我还认为返回键会是问题所在,所以我很惊讶它可以工作。
      • 在控制台上运行的时候,和你描述的一样,看来Eclipse确实是在吞噬\n本身。
      • @Devolus 我认为在这种情况下确实如此。 (谢谢你给了我另一个讨厌 IDE 的理由,我收藏了!)
      【解决方案3】:

      没什么大问题,你只是忽略处理每个字符后的'\n'输入,你可以这样做:

      scanf("%c\n",&z);
      

      这样你就可以避免处理'\n'。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多