You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言连续调用两次scanf函数的异常运行问题排查

问题原因分析

你提供的可复现问题的代码如下:

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

void main ()
{
    char c;
    int choice, dummy;

    do {
        printf ("\n1. Print Hello\n2. Print Javatpoint\n3. Exit\n");
        scanf ("%d", &choice);

        switch (choice)
        {
        case 1:
            printf ("Hello");
            break;
        case 2:
            printf ("Javatpoint");
            break;
        case 3:
            exit (0);
            break;
        default:
            printf ("please enter valid choice");
        }

        printf ("\ndo you want to enter more?");
        scanf ("%d", &dummy);
        scanf ("%c", &c);

    } while (c == 'y');
}

该现象是C语言标准输入缓冲区的字符残留 + 不同scanf格式符的匹配规则差异共同导致的,具体逻辑如下:

  • 首先明确scanf的两个基础规则:
    1. %d格式符只会匹配输入流中的数字字符,遇到非数字字符(比如输入结束按下回车产生的\n换行符)就会终止读取,且不会自动丢弃这个未匹配的非数字字符,会将其残留在标准输入缓冲区中。
    2. %c格式符不会跳过任何前置空白字符(换行、空格、制表符都属于空白字符),会直接读取输入缓冲区中的第一个字符,不管是什么类型。
  • 输入整数时的执行流程:
    你输入1之后按下回车,实际输入到缓冲区的内容是1\n。
    1. 第一个scanf("%d", &dummy)读取到1,匹配成功,将1存入dummy,剩下的\n留在缓冲区中。
    2. 第二个scanf("%c", &c)直接读取到缓冲区里残留的\n,不需要等待你新输入内容,此时c的值为\n,不等于'y',循环条件不成立,程序直接终止。
  • 输入y时运行正常的原因:
    当你输入y时,%d格式符无法匹配字母y,读取失败,y会被留在缓冲区中,接下来%c直接读取到这个y,刚好符合循环条件,因此看起来运行正常。
修复方案

最简单的修复方式是给%c前添加一个空格,让scanf自动跳过所有前导空白字符:

// 把原来的 scanf("%c", &c); 改成
scanf(" %c", &c);

也可以在两次scanf之间调用getchar()吞掉残留的换行符:

scanf("%d", &dummy);
getchar(); // 吃掉缓冲区残留的\n
scanf("%c", &c);

内容的提问来源于stack exchange,提问作者Ashikul Islam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 14:09:04