用std::stoi+手动分段校验最稳妥:需确保恰好4段、每段非空且无前导零(除非为"0")、转整数后在[0,255]内,而inet_pton和正则均易漏判前导零、超范围等业务关键错误。

用 std::stoi + 手动分段校验最稳妥
直接调用现成的 inet_pton 或正则库看似省事,但对 IPv4 字符串合法性判断容易漏掉业务常见陷阱:比如 "01.02.03.04"(带前导零)、"256.1.1.1"(超范围)、"192.168.1."(结尾点号)。标准库函数不报错,但业务上必须拒绝。
推荐手动按点分割 + 逐段转换校验:
- 用
std::string::find或std::stringstream拆出四段,确保恰好 4 段,且每段非空 - 对每段调用
std::stoi(不是atoi),捕获std::invalid_argument和std::out_of_range - 检查原始字符串中该段是否含前导零:若长度 > 1 且首字符为
'0',非法 - 确认转换后值在
[0, 255]区间内
别用 inet_pton 判断 IPv4 字符串合法性
inet_pton 是为“地址转换”设计的,不是“格式校验”工具。它会静默接受 "192.168.1.001"、"192.168.0x1.1"(十六进制写法),甚至部分缩写形式(如 "192.168.1" 被解释为 192.168.0.1),完全不符合“合法 IPv4 字符串”的业务定义。
如果你只关心能否转成二进制地址,那它够用;但你要判断用户输入的字符串是否合规,就必须自己解析。
立即学习“C++免费学习笔记(深入)”;
正则表达式容易写错边界
常见错误是写成 R"(^([0-9]{1,3}\.){3}[0-9]{1,3}$)" —— 这根本没限制数值范围,"999.999.999.999" 也能过。真正安全的正则要穷举 0–9、10–99、100–199、200–249、250–255 五种模式,可读性差且易漏。
更实际的做法是:先用简单正则快速筛掉明显非法结构(如非数字/点、连续点、开头或结尾为点),再走 std::stoi 校验。例如预检正则:R"(^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$)",比全靠正则靠谱得多。
注意 std::stoi 的两个坑
std::stoi 默认只转换“最长有效前缀”,遇到 "123abc" 会返回 123 而不报错。IPv4 每段必须严格由数字构成,所以必须额外检查:转换后剩余字符是否为空。
示例片段:
std::size_t pos;
int val = std::stoi(segment, &pos);
if (pos != segment.length()) {
// 含非数字字符,如 "12a" 或 "01"
return false;
}
另一个坑是:空字符串传给 std::stoi 会抛 std::invalid_argument,所以拆段后必须先判空。
真正容易被忽略的是:不同平台下 std::stoi 对前导零的处理一致(C++11 起明确要求拒绝),但很多人误以为它会自动截断或容忍——它不会。只要字符串含前导零且长度 > 1,std::stoi 就抛异常,这反而是我们想要的行为。


















