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

C语言读取含空格输入异常求助:如何正确处理带空格及换行的输入?

C语言读取含空格输入异常的解决方法

问题场景

读取包含空格的字符串与浮点数组合的输入时输出异常,尝试用fgets配合strtok/strcspn去除换行符仍未解决。

输入示例

3
Programming in C
21.5
Programming in VB
18.5
Programming in Delphi
25.0

错误代码

#include<stdio.h>
#include<string.h>
struct book{
    char name[30];
    double price;
};
int main(){
    int i,n,max=0,min=0;
    scanf("%d",&n);
    struct book bo[10];
    for(i=0;i<n;i++){
        fgets(bo[i].name,sizeof(bo[i].name),stdin);
        strtok(bo[i].name,"\n");
        scanf("%lf\n",&bo[i].price);
        if(bo[i].price>bo[max].price)
            max=i;
        if(bo[i].price<bo[min].price)
            min=i;
    }

    printf("%.2f, %s\n",bo[max].price,bo[max].name);
    printf("%.2f, %s",bo[min].price,bo[min].name);
    return 0;
}

错误输出

21.50, Programming in C
0.00, 

问题根源

scanf("%d", &n)读取整数后,输入缓冲区会残留一个换行符。第一次循环时,fgets直接读取这个换行符作为第一个book.name的内容,导致第一个结构体的name为空;后续scanf读取的21.5被赋值给第一个结构体的price。后续循环中fgets才开始读取真正的书名,但min始终指向第一个空名字的结构体(其初始price为0.0),最终输出异常。

修正方案

核心是清空scanf残留的换行符,以下两种方式均可:

方案1:用getchar()手动丢弃换行符

修改后的代码:

#include<stdio.h>
#include<string.h>
struct book{
    char name[30];
    double price;
};
int main(){
    int i,n,max=0,min=0;
    scanf("%d",&n);
    getchar(); // 读取并丢弃scanf残留的换行符
    struct book bo[10];
    for(i=0;i<n;i++){
        fgets(bo[i].name,sizeof(bo[i].name),stdin);
        // 用strcspn更安全地截断换行符(避免strtok空指针风险)
        bo[i].name[strcspn(bo[i].name, "\n")] = '\0';
        scanf("%lf",&bo[i].price);
        getchar(); // 读取price后的换行符,避免影响下一次fgets
        if(bo[i].price>bo[max].price)
            max=i;
        if(bo[i].price<bo[min].price)
            min=i;
    }

    printf("%.2f, %s\n",bo[max].price,bo[max].name);
    printf("%.2f, %s",bo[min].price,bo[min].name);
    return 0;
}

方案2:用scanf格式串自动跳过换行符

将读取整数和浮点数的scanf语句修改为:

scanf("%d%*c",&n); // %*c表示读取一个字符但不存储,自动吃掉换行符
// ...
scanf("%lf%*c",&bo[i].price); // 读取浮点数后跳过换行符

额外说明

  • strtok(bo[i].name,"\n")存在风险:若fgets读取的内容不含换行(如字符串长度达上限),strtok会返回空指针,无法正确处理。strcspn更稳妥,它会返回换行符的位置,直接替换为\0即可截断字符串。
  • 每次scanf读取浮点数后,输入缓冲区同样会残留换行符,必须处理掉才能让下一次fgets读取正确的书名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:53:13