[英]Converting IP addresses from char * to uin32_t
我的灵感来自IP地址到整数的转换
我的代码如下所示:
uint32_r parseIPV4string(char * ipAddress){
char ipbytes[4];
sscanf(ipAddress, "%uhh.%uhh.%uhh.%uhh", &ipbytes[3], &ipbytes[2], &ipbytes[1], &ipbytes[0]);
return ipbytes[0] | ipbytes[1] << 8 | ipbytes[2] << 16 | ipbytes[3] << 24;
}
实际上,实际上是一个精确的副本,但是我的问题是我的IP地址无法正确显示。 我震惊和敬畏地看着“ 129.173.118.0”和“ 129.173.31.187”都返回2164260864
有人可以解释发生了什么吗?
也许我使用的解析器不正确,我不确定它的工作原理,即“%uhh”。 对我来说是新手,我不知道该return语句中发生了什么。
您的sscanf
失败。 发生这种情况时,参数将处于不确定状态。 因此,您的return
语句返回垃圾。
%uhh
表示读入unsigned int
,然后将字母'h'
匹配两次。 如果您输入的字符串实际上没有在第一个数字之后包含h
,则匹配失败,并且sscanf
将返回1
(如果没有第一个数字,则返回0
)。
您可能是说%hhu
,以读取整数并存储在unsigned char
,但是您还需要使ipbytes
为unsigned char
以匹配格式说明符。 纯字符或带符号char的说明符为%hhd
。
这个数组应该是无符号的,无论如何,否则你|
稍后会搞砸(请记住,负数设置了很多1
位,以2的补码表示)。
进一步的问题是,如果您的系统中使用,即使有32位int,然后unsigned char
,所述表达ipbytes[3] << 24
原因如果满足高比特未定义行为ipbytes[3]
符号整数溢出被设置时,由于:不幸的是, 整数提升将 unsigned char
提升为一个有符号的int
。
最后,如果系统具有16位int,则<< 16
和<< 24
完全失败。
编写该函数的一种可靠方法是避免出现任何不良提升:
uint32_t parseIPV4string(char const * ipAddress)
{
unsigned int ip[4];
if ( 4 != sscanf(ipAddress, "%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]) )
return 0; // or some other indicator or error
return ipbytes[3] + ipbytes[2] * 0x100 + ipbytes[1] * 0x10000ul + ipbytes[0] * 0x1000000ul;
}
如果您真的想使用|
与<<
那么或者使用一些丑陋的铸件; 或将ip
更改为uint32_t
类型,在这种情况下,必须将"%u"
替换为"%" SCNu32
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.