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
相关产品推荐
相关产品推荐

