2017-08-31 25 views
0

我想将IP字符串转换为长c++, 我宁愿不使用任何inet的函数。IP到长转换C++

我用下面的函数将其转换:

unsigned long IPStringToLong(std::string IPAddr) 
{ 
     unsigned char aClassByte, bClassByte, cClassByte, dClassByte; 
     sscanf_s(IPAddr.c_str(), IP_TO_BYTES_FORMAT, &aClassByte, &bClassByte, &cClassByte, &dClassByte); 
     unsigned long IP = (aClassByte << 24) | (bClassByte << 16) | (cClassByte << 8) | dClassByte; 
     std::cout << IP << std::endl; 
     return IP; 
} 

IP_TO_BYTES_FORMAT这里定义:

#define IP_TO_BYTES_FORMAT "%hhu.%hhu.%hhu.%hhu"

印刷只是为了调试。

Visual Studio引发运行时错误:Stack corruption around variable bClassByte,但转换确实有效。

当我定义的格式short S(和改变路线的代码):

#define IP_TO_BYTES_FORMAT "%hu.%hu.%hu.%hu"

它工作得很好,我不明白为什么。

+0

'“%hh”'不是有效的格式。你的意思是“%胡”吗? –

+0

sscanf类函数不带类型安全参数。 %u格式需要指向整数的指针,你给char(byte)指针,sscanf函数doest知道这一点。下一个变量被破坏(运行时的调试版本发出警告) –

+0

@Someprogrammerdude是的,谢谢! –

回答

1

你说你正在使用C++,但你实际上正在调用一个C函数。这是你的问题的原因:你已经找到了一些C99代码。 %hhu是C99。您的Visual Studio版本不实现C99。

修复很容易,因为无论如何您需要修复更多。不要使用short;点划格式允许8.248.8.16。换句话说,您需要%d.%d.%d.%d,并检查您实际读取的字段数量(返回值为scanf)。虽然我们做得对,但我们不妨使用int parts[4]而不是a,b,c,d

+0

非常感谢!没有完全理解你的关于虚线四格式的注释允许8.24等等。你能指点我读些什么吗? –

+0

@OferArial:查看维基百科。基本上,'10.1234567'是'10.x.x'范围内的有效地址。要将其转换为长整型,可以计算'(10 << 24)+ 1234567'。你不能在短时间内适应'1234567'。 – MSalters

+0

@OferArial:IPv4地址可以用4种不同格式之一表示:a.b.c.d,a.b.c,a.b和a。并且每个单独的数字本身可以用十进制(最常见),十六进制或八进制格式表示。 ['inet_addr()'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms738563.aspx)和其他类似的函数为您处理所有这些格式。请阅读'inet_addr()'文档以获取这些格式所代表的内容。您显示的代码仅支持十进制格式的“a.b.c.d',这是最常用的格式,但绝对不是唯一可用的格式。 –