如何在sscanf中正确转义右方括号以提取带方括号的IP及端口?
问题原因
- 你最初使用的
%[^:]格式符不符合匹配逻辑:%[^:]属于sscanf的扫描集语法,作用是匹配所有不为冒号的字符直到遇到第一个冒号就停止匹配,而IPv6地址内部本身包含多个冒号,会导致匹配提前终止。 - sscanf扫描集有明确语法规则:如果要把右方括号
]作为扫描集的匹配字符之一,必须将]放在[或否定符^之后的第一个位置,否则会被识别为扫描集的结束标记,这也是你误以为]被误识别的原因。
解决方法
调整扫描集的写法,先匹配到右方括号前的所有内容,再匹配原字符串里的右方括号,最后匹配端口,补全IP部分的右方括号即可,正确代码如下:
#include <cstring> #include <iostream> int main(int argc, char const* argv[]) { char ip[64] = { 0 }; int port{ 0 }; // 格式串说明: // %[^]] 匹配所有非]的字符,存入ip变量 // ] 匹配原字符串中的右方括号 // :%d 匹配后续的冒号和端口数字 int match_cnt = sscanf("[192:4545:454:e33]:8888", "%[^]]]:%d", ip, &port); if (match_cnt == 2) { // 给IP补全右方括号 strcat(ip, "]"); std::cout << "ip: " << ip << std::endl; std::cout << "port: " << port << std::endl; } else { std::cout << "字符串格式不符合预期,匹配失败" << std::endl; } return 0; }
运行输出
ip: [192:4545:454:e33] port: 8888
如果不想手动拼接右方括号,也可以直接将]加入扫描集,写法为%[]0-9a-fA-F:.[]:%d,不过这种写法需要手动穷举所有允许出现在IPv6地址中的字符,容错性更低,更推荐上面的写法。
内容的提问来源于stack exchange,提问作者shdxiang
相关产品推荐
相关产品推荐

