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

C语言中scanf()后调用gets()、scanf("%c")无法接收输入问题咨询

问题分析与解决

根本原因:输入缓冲区残留换行符

你遇到的两个异常本质是同一个底层逻辑导致的:C语言所有标准输入函数共享同一个输入缓冲区,不同函数对空白字符(换行、空格、制表符等)的处理规则不同,导致前一次输入的残留字符被后一个函数误读取。

  • scanf("%s") 读取字符串时,只会读取空白符之前的有效内容,会把触发输入结束的换行符\n遗留在输入缓冲区中
  • gets() 函数的逻辑是只要读到换行符就立刻结束读取,并且将换行符替换为字符串结束符\0。当它紧跟在scanf("%s")之后调用时,会直接读取到缓冲区里残留的\n,直接返回空内容,看起来就像没有接收用户输入一样。
  • 同理scanf("%c")是读取任意单个字符,包括空白符,所以也会直接把残留的\n当成有效输入读走,不会等待用户输入新内容。

解决方法

1. 清理缓冲区残留的空白符

在scanf调用之后、调用gets/scanf("%c")之前,主动把缓冲区里的残留换行符清除,两种常用方案:

  • 调用一次getchar()读取掉残留的换行符,适合确定只残留了一个换行的场景
  • 用while(getchar()!='\n');循环清空缓冲区所有残留内容,适合残留内容不确定的场景

2. 针对scanf("%c")的简易处理

在%c前面加一个空格,写成scanf(" %c", &ch);,这个空格会告诉scanf自动跳过所有前置的空白字符,再读取有效字符。

3. 废弃gets()函数,替换为更安全的fgets()

gets()因为没有边界检查,非常容易造成缓冲区溢出漏洞,早在C11标准就被正式移除了,推荐用fgets(add, sizeof(add), stdin);替代,功能和gets一致但有长度保护。


修改后的可运行示例代码

#include<stdio.h>
#include<conio.h>
#include<string.h>

void main(){
    char username[25],Email[40],contact[15],add[80];
    clrscr();
    printf("Enter all your details below\n");

    printf("username :");
    scanf("%s", username);
    // 清空缓冲区残留的换行符
    while(getchar() != '\n');

    printf("Enter your Address:");
    fgets(add, sizeof(add), stdin);
    // fgets会把读到的换行符存进字符串,不需要的话可以手动去掉
    add[strcspn(add, "\n")] = '\0';

    printf("Email ID :");
    scanf("%s",Email);
    while(getchar() != '\n');

    printf("Contact :");
    scanf("%s",contact);
    while(getchar() != '\n');

    printf("\nYour username is %s\n",username);
    printf("Your Email ID is %s\n",Email);
    printf("Your Contact No. is %s\n",contact);
    printf("Your Address is %s\n",add);

    getch();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 20:57:03