如何在C语言中使用scanf读取包含空格的字符串?
解决C语言读取带空格完整姓名的问题
你的代码里,scanf("%s")会把空格、换行这类空白字符当作输入结束标志,所以只能读取姓名的第一个单词。另外,读取整数n后,输入缓冲区残留的换行符会被后续读取操作直接捕获,导致第一次读姓名时拿到空内容。下面是两种C语言的可行解决方案:
方法一:修正scanf格式串
在scanf的格式串前加一个空格(用来跳过所有前置空白字符,包括之前的换行),同时使用%[^\n]格式说明符读取直到换行的所有字符:
#include <stdio.h> #include <stdlib.h> int main() { int n; struct caract { char nume[30]; float medie ; float note[4]; int prom; }; scanf("%d", &n); struct caract elev[n]; for(int i=0;i<n;i++) { // 格式串前的空格自动跳过前置空白,%[^\n]读取到换行前的所有字符 scanf(" %[^\n]", elev[i].nume); elev[i].medie=0.0; elev[i].prom=1; for(int j=0;j<4;j++) { scanf("%f", &elev[i].note[j]); elev[i].medie += elev[i].note[j]; } elev[i].medie /= 4; // 补充prom的判断逻辑(比如根据成绩是否及格) if(elev[i].prom==1) { printf("%s ", elev[i].nume); printf("%.2f\n", elev[i].medie); } } return 0; }
为了避免缓冲区溢出,建议限制读取的最大字符数(留一个位置给终止符'\0'):
scanf(" %29[^\n]", elev[i].nume);
方法二:使用fgets(更推荐)
fgets可以读取一整行输入(包括空格),是处理带空格字符串更安全的方式。需要注意fgets会把输入末尾的换行符也读入数组,需手动去除:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int n; struct caract { char nume[30]; float medie ; float note[4]; int prom; }; scanf("%d", &n); getchar(); // 跳过n后面的换行符 struct caract elev[n]; for(int i=0;i<n;i++) { // 读取整行到数组,最多读取sizeof(elev[i].nume)-1个字符 fgets(elev[i].nume, sizeof(elev[i].nume), stdin); // 用strcspn定位换行符,替换为字符串终止符 elev[i].nume[strcspn(elev[i].nume, "\n")] = '\0'; elev[i].medie=0.0; elev[i].prom=1; for(int j=0;j<4;j++) { scanf("%f", &elev[i].note[j]); elev[i].medie += elev[i].note[j]; } elev[i].medie /=4; // 补充prom的判断逻辑 if(elev[i].prom==1) { printf("%s ", elev[i].nume); printf("%.2f\n", elev[i].medie); } getchar(); // 跳过成绩输入后的换行符,避免影响下一次姓名读取 } return 0; }
注意事项
- 确保输入的姓名长度不超过
nume数组的大小(30),避免缓冲区溢出;如需处理更长姓名,要适当增大数组容量。 - 使用
scanf("%[^\n]")时,若用户输入字符过多会触发溢出,必须限制读取长度。
内容的提问来源于stack exchange,提问作者Filip Ion
相关产品推荐
相关产品推荐

