如何让scanf忽略当前行指定位置之后的所有输入?
解决scanf忽略指定位置后输入的问题
这个场景太常见了——处理ls输出这类格式的文本时,文件名带空格简直是scanf的噩梦,一不小心就把后续输入搞乱了。针对你的需求,有两种简单可靠的方法:
方法1:用scanf的格式符直接跳过剩余内容
scanf支持一种特殊的格式符%*[^\n],可以帮你跳过当前位置到行尾的所有字符(不包括换行符本身)。结合你的输入格式,代码可以这么写:
#include <stdio.h> int main() { char perm[11], user[20], group[20]; int links, size; // 读取前5个字段,然后跳过行内剩余所有内容 while (scanf("%s %d %s %s %d %*[^\n]", perm, &links, user, group, &size) == 5) { // 这里处理你读取到的权限、链接数、所有者等数据 printf("权限: %s, 链接数: %d, 用户: %s, 组: %s, 大小: %d\n", perm, links, user, group, size); // 别忘了吃掉换行符,否则下一次scanf会读到空行 getchar(); } return 0; }
解释一下关键部分:
%*[^\n]:%[^\n]表示匹配所有不是换行符的字符,前面的*表示“只匹配但不存储到变量”,这样就直接忽略了从423之后到行尾的所有内容(包括带空格的文件名)。- 最后调用
getchar()是因为%*[^\n]不会处理换行符,留在输入缓冲区里会影响下一次循环的读取。
方法2:先读整行再解析(更稳妥)
如果担心输入行长度不确定,或者不想处理换行符的问题,更推荐先把整行读进来,再用sscanf解析前面的字段——这样剩余的内容自然就被忽略了,完全不用管文件名有没有空格:
#include <stdio.h> int main() { char line[256]; // 根据实际需求调整数组大小 while (fgets(line, sizeof(line), stdin) != NULL) { char perm[11], user[20], group[20]; int links, size; // 只解析前5个字段,剩下的内容直接无视 if (sscanf(line, "%s %d %s %s %d", perm, &links, user, group, &size) == 5) { printf("权限: %s, 链接数: %d, 用户: %s, 组: %s, 大小: %d\n", perm, links, user, group, size); } } return 0; }
这种方法的优势是:fgets会把整行(包括换行符)都读进line数组,sscanf只处理你需要的部分,剩下的内容不会干扰后续的输入读取,容错性更强。
内容的提问来源于stack exchange,提问作者Lukasz D
相关产品推荐
相关产品推荐

