<span style="font-family: Arial, Helvetica, sans-serif;">// demo: 判断IP 字符串是否为有效地址 2014-9-23 16:00:37</span>
#include "stdafx.h"
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
#define MAX_EDIT_IP 128
bool checkV4(const char *p)
{
if(NULL == p)
{
return false;
}
else
{
while(*p != '\0')
{
if(*p <= '9' && *p++ >= '0')
continue;
else
return false;
}
}
return true;
}
bool CheckIpV4(char *ip)
{
char *temp = ip;
int count = 0;
int flag = 0;
// 这里有意把 设为MAX_EDIT_IP,其实只要4个字节就够了。。但你要考虑别人本来就输入的不合法的情况
// 所有在有编辑框时应限制字数的输入。// 2014-9-23 16:00:20
char s1[MAX_EDIT_IP],s2[MAX_EDIT_IP],s3[MAX_EDIT_IP],s4[MAX_EDIT_IP]; // IP Address: s1.s2.s3.s4
int ip_1,ip_2,ip_3,ip_4;
while(*temp != '\0')
{
if(*temp == '.')
count++;
temp++;
}
flag = sscanf(ip,"%[^.].%[^.].%[^.].%[^.]",s1,s2,s3,s4);
if(count != 3 || flag != 4)
{
return false;
}
if(!(checkV4(s1) && checkV4(s2) && checkV4(s3) && checkV4(s4)))
{
return false;
}
ip_1 = atoi(s1);
ip_2 = atoi(s2);
ip_3 = atoi(s3);
ip_4 = atoi(s4);
if( (0 <= ip_1 && ip_1 <= 255) && (0 <= ip_2 && ip_2 <= 255)
&& (0 <= ip_3 && ip_3 <= 255) && (0 <= ip_4 && ip_4 <= 255)
)
{
return 1;
}
else
{
return false;
}
return true;
}
bool checkV6(const string& str)
{
int nLen = str.length();
if (nLen > 4)
{
return false; // IPV6每一小段最多只有4个字符,否则为不合法
}
for (int i = 0; i < nLen; ++i)
{
if ((str[i] >= '0' && str[i] <= '9') || \
(str[i] >= 'a' && str[i] <= 'f') || \
(str[i] >= 'A' && str[i] <= 'F') )
{
continue;
}
else
{
return false;
}
}
return true;
}
bool CheckIpV6(char *ip)
{
string str(ip);
string::size_type index = str.find(':');
if (string::npos == index) // not found!
{
return false;
}
index = str.find("%");
if (string::npos != index)
{
str = str.substr(0, index);
}
int nCnt = 0;
int nColonCnts = 0; // 冒号(:) 出现的次数
string strTmp;
while(1)
{
index = str.find_first_of(':');
if (string::npos != index)
{
++ nColonCnts;
strTmp = str.substr(0, index);
if (!strTmp.empty())
{
if (!checkV6(strTmp))
{
return false;
}
}
str = str.substr(index+1);
if (str.length() >= 1)
{
if (str[0] == ':')
{
// 统计 :: (两个冒号) 一起出现的次数,注意;IPV6 只能有一个 :: 的出现,否则为不合法
++nCnt;
}
}
}
else
{
if (nColonCnts > 7) // IPV6 最多只有8小段,即7个冒号分割。
{
return false;
}
if (nCnt >= 2) // :: 最多 只能出现一次
{
return false;
}
return checkV6(str);
}
}
// return true;
}
bool CheckIp(char *ip)
{
string str(ip);
string::size_type index = str.find(':');
if (string::npos != index)
{
return CheckIpV6(ip);
}
else
{
return CheckIpV4(ip);
}
return true;
}
int main()
{
// example
if (CheckIp("1207.0.0.1"))
{
cout << "check Ip Address Valid.. " << endl;
}
else
{
cout << "check Ip Address Invalid.." << endl;
}
// example
if (CheckIp("fe80:febd:81:32:4323:432:243:432:89::%3")) // IpV6
{
cout << "check Ip Address Valid.. " << endl;
}
else
{
cout << "check Ip Address Invalid.." << endl;
}
return 1;
}
情景: 近来在自己的编辑对话框中需要用到输入网络IP, 刚开始自己写了一段代码来判断 一串字符是否为合法的IP 地址(注意:有些不完善,比如::fe80:a00:37f%ffdf 是不合法的,因为%后面不合规则。 )
后来,发现还是用MFC 对话框中的 Ip Address Control (在工具条那里拖过来即可),控件ID为 IDC_NETADDRESS, 并关联一个变量 : CNetAddressCtrl m_netaddrctrl;
并在需要校验IP 地址是否正确的函数 里添加如下代码段
// Prepare the mask
DWORD dwAddrMask = 0;
dwAddrMask |= NET_STRING_IPV4_ADDRESS | NET_STRING_IPV6_ADDRESS;
NET_ADDRESS_INFO nfo;
NC_ADDRESS addr;
addr.pAddrInfo = &nfo;
// Validate
m_netaddrctrl.SetAllowType(dwAddrMask);
HRESULT hr = m_netaddrctrl.GetAddress(&addr);
if (S_OK == hr)
{
// 自己需要作其他处理的代码,比如提示框得。。这里省略
}
else
{
//...
}