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

for循环中使用字符集格式的scanf为何无法正常读取输入?

问题原因

你的判断完全正确,故障的核心诱因就是scanf("%d",&n)读取整数后,残留在输入缓冲区中的尾部换行符。

执行scanf("%d",&n)时,函数只会读取连续的数字字符转换为整型存入变量n,你输入完数字按下的回车对应的\n字符不会被%d格式符匹配消费,会一直留在输入缓冲区中。
进入for循环后,你使用的%27[^\n]格式符匹配规则是「读取最多27个非换行符的字符」,第一次循环时缓冲区首字符就是残留的\n,会直接导致匹配失败:

  • 匹配失败时scanf不会对in数组执行任何写入操作,而in是栈上未初始化的局部数组,存储的是内存中的随机垃圾值,直接printf输出就会出现乱码,你看到的笑脸字符就是随机字节恰好命中了ASCII扩展字符集的对应编码。
  • 由于%27[^\n]匹配失败,scanf会直接提前返回,后面跟着的%*c(用来消费读取字符串后剩下的换行符)根本不会执行,缓冲区里的\n会一直留存,后续每一轮循环都会重复「匹配失败→输出垃圾值」的流程,全程不会等待用户输入。
修复方案
  • 读取完整数n后,立刻清空输入缓冲区中残留的所有字符直到换行,不要用C标准未定义的fflush(stdin),用循环读字符的方式兼容性最好:
    while(getchar() != '\n');
    
  • 修正不规范的代码写法:
    • 数组名本身就是首元素地址,scanf读字符串时不需要对数组名取&;
    • 不要用非标准的void main写法,C标准规定main函数返回值为int;
    • 字符数组读入前先初始化为全0,避免匹配失败时输出未初始化的内存乱码;
    • 每轮读取完字符串后,统一用循环清空当前行剩余的所有字符(包括换行),兼容用户直接敲回车输入空行、输入内容超过27个字符的场景,避免残留字符影响下一轮输入。

修复后的完整可运行代码:

#include <stdio.h>
int main()
{
    int n;
    printf("Loop:\n");

    scanf("%d", &n);
    // 清空读整数后残留的缓冲区内容
    while (getchar() != '\n');

    for (int i = 0; i < n; ++i)
    {
        char in[28] = {0};
        scanf("%27[^\n]", in);
        // 清空当前行剩余所有字符,包括换行
        while (getchar() != '\n');
        printf("%s\n", in);
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:57:21