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

scanf用%c接收输入却可处理字符串?递归scan函数运行原理解析

递归scan函数的运行流程与scanf行为解析

先看这段代码的完整逻辑:

void scan(void){
    char item;
    scanf("%c",&item);
    if(item == '#'){
        printf("\n");
        return;
    }
    printf("%c",item);
    scan();
}

代码运行流程

  1. 首次调用scan()时,先定义局部变量item,接着通过scanf("%c", &item)从输入中读取一个字符。
  2. 如果读取到的字符是#,就打印换行符,然后直接return结束当前scan()调用。
  3. 如果不是#,就打印该字符,接着递归调用scan()自身,重复上述步骤。
  4. 当某个递归分支遇到#返回后,会逐层回到上一层scan()调用,但上一层已经执行完printf和递归语句,所以直接结束,直到回到最初的调用,整个函数执行完毕。

为什么递归中的scanf会自动逐个读字符?

核心原因是控制台输入采用行缓冲机制:

  • 当你在控制台输入一串字符并按下回车时,输入的所有字符(包括回车符)会被一次性存入系统的输入缓冲区,而非每次只传一个字符给程序。
  • 每次调用scanf("%c", &item)时,它不会等待你手动输入新字符,而是直接从输入缓冲区取出下一个未被读取的字符。只有当输入缓冲区为空时,scanf才会阻塞,等待你输入新内容。

举个实际例子:如果你输入hello#world然后回车,输入缓冲区会依次存放h、e、l、l、o、#、w、o、r、l、d、\n(回车符)。

  • 前五次递归调用会依次读取h、e、l、l、o,逐个打印后继续递归。
  • 第六次调用读取到#,打印换行后返回,整个递归链条结束,缓冲区里剩下的w、o、r、l、d、\n不会被处理。

另外要注意:scanf("%c")会读取所有字符,包括空格、回车这类空白字符,不像%s格式符会自动跳过前导空白。

内容的提问来源于stack exchange,提问作者Mingyu Su

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:55:03