如何用sscanf忽略可变数量空白字符解析代理文件?
用sscanf解析多空白分隔的代理文件解决方案
别担心,sscanf本身就会自动跳过任意数量的空白字符(不管是2个还是4个空格,甚至制表符),根本不用额外做什么。你之前的困惑主要是没注意到:%s确实读到空格就停,但如果字段本身不带空格,sscanf会自动跳过字段之间的所有空白,直接读下一个字段。
针对你给出的代理数据,分两种场景处理:
场景1:所有字段都不带空格
如果像第二行那样,国家是单个单词(Ukraine),直接按顺序写格式符就行:
char ip[16], protocol[10], country[30], anonymity[10], latency[10], success_rate[10], uptime[20]; int port; // 不管字段间有多少空格,sscanf都会自动跳过 sscanf(line, "%s %d %s %s %s %s %s %s", ip, &port, protocol, country, anonymity, latency, success_rate, uptime);
测试你给的两行数据,这个写法完全能正确读取IP、端口、协议等所有字段。
场景2:字段包含空格(比如United States)
如果遇到像第一行那样国家带空格的情况,%s就会只读到"United",剩下的"States"会被当成下一个字段,这时候就得换方式:
方法1:利用固定字段截断
比如Elite是固定的匿名类型字段,我们可以读取到Elite之前的内容作为国家:
char ip[16], protocol[10], anonymity[10] = "Elite"; int port; char country[50], latency[10], success_rate[10], uptime[20]; // %[^E]会读取到第一个'E'(Elite的首字母)之前的所有内容 sscanf(line, "%s %d %s %[^E]%s %s %s %s", ip, &port, protocol, country, anonymity, latency, success_rate, uptime); // 手动去掉国家字段末尾的空格 country[strcspn(country, " \t")] = '\0';
方法2:用%n记录位置截取
如果字段规则不固定,用%n记录读取到的位置,再截取国家部分:
char ip[16], protocol[10], anonymity[10], latency[10], success_rate[10], uptime[20]; int port, start_pos, end_pos; char country[50]; // %n会把当前读取的字节数存在变量里 sscanf(line, "%s %d %s %n%*[^E]Elite%n %s %s %s", ip, &port, protocol, &start_pos, &end_pos, latency, success_rate, uptime); // 截取从start_pos到end_pos之间的内容(减去Elite的长度和前面的空格) strncpy(country, line + start_pos, end_pos - start_pos - 6); country[end_pos - start_pos - 6] = '\0';
核心总结
- 只要字段本身不带空格,
%s就能自动跳过字段间的所有空白,直接读下一个字段,完全不用管空白数量。 - 只有字段含空格时才需要特殊处理,
%[]格式符或者%n记录位置是最常用的两种办法。
内容的提问来源于stack exchange,提问作者Mihajlo Spasic
相关产品推荐
相关产品推荐

