判断IP 字符串是否为有效地址

<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
{
 //... 
}







  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值