为什么scanf("%[^ ]s")无法捕获带空格的字符串?如何解决?
问题根因
- 格式符错误:
%[^\n]s写法有误,%[^\n]是独立的扫描集格式说明符,后续的s是多余字符,会要求scanf匹配输入流中紧跟在非换行字符后的s,正常输入回车结束时不存在该字符,导致匹配失败,无法读取输入。 - 缺少长度限制:
%[^\n]未指定读取长度,输入字符超过99个时会溢出长度为100的字符数组,引发内存越界。 - 无前导空白处理(可选优化点):
%[格式符默认不跳过输入缓冲区的前导空白字符,若之前有残留换行符会直接匹配失败。
修复方案
将scanf行修改为如下写法即可:
scanf(" %99[^\n]", c);
格式符说明:
- 开头的空格:跳过输入缓冲区中所有前导空白(包括换行、空格、制表符等)
%99[^\n]:最多读取99个非换行字符,自动在末尾添加\0结束符,不会溢出数组
完整修正代码
#include <stdio.h> int main() { errno_t inputfile; FILE *stream; inputfile = fopen_s(&stream, "inputfile.txt", "w"); // 增加文件打开成功判断,避免后续操作异常 if (inputfile != 0 || stream == NULL) { printf("文件打开失败"); return 1; } printf("Enter a string. Press ENTER to exit\n"); char c[100] = {0}; // 初始化数组,避免匹配失败时输出垃圾值 // 修正后的scanf写法,增加返回值判断处理空输入场景 if (scanf(" %99[^\n]", c) != 1) { c[0] = '\0'; } printf("%s", c); fprintf(stream, "%s", c); fprintf(stream, "%s", "ENTER is a correct ending"); fclose(stream); return 0; }
补充说明
如果需要读取整行输入(包括开头的空格),也可以直接使用fgets(c, sizeof(c), stdin)函数,该函数专门用于读取一行输入,自动限制读取长度,写法更简单不易出错。
内容的提问来源于stack exchange,提问作者CPKEN
相关产品推荐
相关产品推荐

