自己写的一个IP地址解析函数

网上很多,socket库里好像也有,但是还是想自己写一个。自我要求有两点,代码要少(要晦涩),支持超网掩码格式。

/*!
 * @param pcInt
 * String to parse, don't support negative integer.
 * 
 * @param iLimit
 * Only parse a number of chars which is less than iLimit.
 * The largest choice? Use 10 for int32, 5 for int16. 
 *
 * @param ppc
 * returns the pointer where the parser finally reached.
 * Pass NULL if you don't need this.
 * 
 * @returns
 * -1 indicates a failure
 * otherwise returns the integer parsed.
 * 
 */
int pc2UnsignedInt(const char* pcInt, int iLimit, const char** ppc)
{
	int iRet = 0;
	const char* pc = pcInt;
	while (*pc >= '0' && (*pc - '0') < 10 && iLimit > 0)
	{
		--iLimit;
		iRet = iRet * 10 + (*pc++ - '0');
	}
	iRet = (pc == pcInt) ? -1 : iRet;
	if (ppc)
	{
		*ppc = pc;
	}
	return iRet;
}
 
/*!
 * @param pcIP
 * String representing an IPv4 address.
 * pcIP should end with space or nothing.
 * eg. "192.168.1.101", "192.168.1.101 " and "192.168.1.101 blabla" are all valid.
 * eg. "192.168.1.101blabla" is not valid.
 * Forms like "192.168.1.101/24" is also supported.
 *
 * @param pi1
 * @param pi2
 * @param pi3
 * @param pi4
 * Pass NULL to them if you don't need these values.
 * 
 * @returns
 * -1 indicates a failure.
 * Success when typical IPv4 (eg. "192.168.1.101") : 33
 * Success when IPv4 plus netmask code (eg. "192.168.1.101/24") : netmask code (0..32)
 * 
 */
int IPv4Parser(const char* pcIP, int* pi1, int* pi2, int* pi3, int* pi4)
{
	int iRet = -1, ai[4] = {0}, i = -1;
	do 
	{
		ai[++i] = pc2UnsignedInt(pcIP, 3, &pcIP);
	} while ( ai[i] >= 0 && ai[i] <= 255 && i < 3 && *pcIP++ == '.' );
	//} while ( ai[i] >= 0 && ai[i] <= 255 && i < 3 && ( i < 3 ? (*pcIP++ == '.') : TRUE ) );
	if (i == 3 && ai[3] >= 0 && ai[3] <= 255)
	{
		if (*pcIP == '/')
		{
			iRet = pc2UnsignedInt(++pcIP, 2, &pcIP);
			iRet = (*pcIP == '\0' || *pcIP == ' ') && iRet >= 0 && iRet <=32 ? iRet : -1;
		}
		else if (*pcIP == '\0' || *pcIP == ' ')
		{
			iRet = 33;
		}
	}
	if (iRet != -1)
	{
		if (pi1)
		{
			*pi1 = ai[0];
		}
		if (pi2)
		{
			*pi2 = ai[1];
		}
		if (pi3)
		{
			*pi3 = ai[2];
		}
		if (pi4)
		{
			*pi4 = ai[3];
		}
	}
	return iRet;
}

在VS2008下测试过,容错性应该还不错。尚未在纯C的编译器下测试,可能需要修改。

第一个函数也算是个副产品,把字符串转换为整数,功能比crt里面的稍多一些。

调用示例(C++):

	int a, b, c, d;
	int iMaskCode = IPv4Parser("192.168.123.101/23", &a, &b, &c, &d);
	std::bitset<8> abitsetNetMask[4];
	for (int i = 0; i < 4; ++i)
	{
		for (int j = 0; j < 8; ++j)
		{
			if (iMaskCode > 0)
			{
				abitsetNetMask[i].set(7 - j); //Eh, it's weird, to_ulong think bit 0 is at the right side...
				--iMaskCode;
			}
		}
	}
	char acNetMask[18] = {0}; 
	sprintf_s<>(acNetMask, "%d.%d.%d.%d", abitsetNetMask[0].to_ulong(), abitsetNetMask[1].to_ulong(), abitsetNetMask[2].to_ulong(), abitsetNetMask[3].to_ulong());

 大意就是把192.168.123.101/23解析出来,然后根据/23生成一个子网掩码的字符串。

当然普通的不带超网掩码的字符串也能解析,例如192.168.123.101。

详情参考注释。

你可能感兴趣的:(C++,c,socket,C#,J#)