繁体   English   中英

将IP地址从char *转换为uin32_t

[英]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 ,但是您还需要使ipbytesunsigned 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM