long ip2long( char *ip )
{
long ip2long = 0;
char B1[4], B2[4], B3[4], B4[4];
int D1, D2, D3, D4 = 0;
sscanf(ip, "%s.%s.%s.%s", B1, B2, B3, B4);
D1 = atoi(B1);
D2 = atoi(B2);
D3 = atoi(B3);
D4 = atoi(B4);
if(D1 > 255 || D2 > 255 || D3 > 255 || D4 > 255)
return 0;
ip2long = D1*256*256*256+D2*256*256+D3*256+D4;
return ip2long;
}
输入数据:127.1.1.2
为什么 D1 == 127,但 D2、D3 和 D4 == 0?
---更新--- 现在代码是
unsigned long ip2long( char *ip )
{
unsigned long ip2long = 0;
unsigned int D1, D2, D3, D4 = 0;
sscanf(ip, "%u.%u.%u.%u", &D1, &D2, &D3, &D4);
if(D1 > 255 || D2 > 255 || D3 > 255 || D4 > 255)
return 0;
ip2long = D1*256*256*256+D2*256*256+D3*256+D4;
return ip2long;
}
Di 没问题,但还有另一个麻烦:127.1.1.2 的结果是 2130772226 而不是 2130772225,195.98.157.132 的结果是 -1016947324... 为什么?
--- 更新 2 --- 没关系,有 %d 代替 %u。
Kornel Kisielewicz 感谢您介绍 inet_addr 函数:)
PS 抱歉我的英语不好=\
问题已关闭。
最佳答案
正如 fizzer 所指出的,%s
消耗了整个字符串——在这种情况下,危险地将其复制到 S1 的末尾之后。如果将 sscanf() 结果与 4 进行比较,就会有很大的线索!不要假设事情会起作用,尤其是在解析来自程序外部的输入时。 atoi
忽略尾随的垃圾,因此即使使用 %[^.]
字符串格式,它会在一段时间内停止,它也会处理像 192,3.2x 这样的垃圾值。 3.1
忽略 ,3
和 x
。
fizzer 对 ("...%d...", &D1...)
的建议是一个好的开始,但你仍然必须将结果与 4 进行比较,否则无效的字符串如 "你好”只会让 D1、D2、D3 和 D4 保持不变。负值将被接受。请注意,只有 D4 设置为 0 - 其他值不受该行尾随 = 0
的影响,并且可能包含来自堆栈的旧垃圾值,这些值可能会或可能不会通过稍后针对 255 的检查.
总结:
unsigned long ip2ulong(char *ip)
{
unsigned u1, u2, u3, u4;
return sscanf(ip, "%u.%u.%u.%u", &u1, &u2, &u3, &u4) == 4 &&
u1 <= 255 && u2 <= 255 && u3 <= 255 && u4 <= 255
? u1*256*256*256 + u2*256*256 + u3*256 + u4 : 0;
}
关于c++ - sscanf 麻烦吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5268646/