1.输入一个IP地址字符串(支持16进制和10进制),判断ip是否合法,例如ip为“192.1.0.1”返回ture,ip为“266.266.266.1”,返回false.
实现函数:int checkIP(const char *str);
程序代码如下
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
static int isString_Hex(char *p)
{
int ret = 0;
if (p == NULL)
{
ret = 0;
}
else
{
while (*p)
{
if (((*p >= 'a') && (*p <= 'f')) || ((*p >= 'A') && (*p <= 'F')))
{
ret = 1;
break;
}
else
{
ret = 0;
}
p++;
}
}
return ret;
}
/***
***:checkIP
***Function:判断ip地址是否合法
***Input: str IP地址
***Output: TRUE 合法
FALSE 不合法
****/
int checkIP(const char *str)
{
//const char * str 表示其指针所指向的内容是只读的,不能被修改
//ip地址默认采用IPv4的点分十进制法,合法地址为0.0.0.0-255.255.255.255
int ret = 0;
const char * split = ".";
char *str1 ;
char * p;
int seg_num = 0;
int ip[10] = {0};
long num = 0;
int i = 0;
int correct = 0;
/*
char* strtok (char* str,constchar* delimiters );
函数功能:
切割字符串,将str切分成一个个子串
函数参数:
str:在第一次被调用的时间str是传入需要被切割字符串的首地址;在后面调用的时间传入NULL。
delimiters:表示切割字符串(字符串中每个字符都会 当作分割符)。
函数返回值:
当s中的字符查找到末尾时,返回NULL;
如果查不到delimiter所标示的字符,则返回当前strtok的字符串的指针。
*/
if (str == NULL)
{
printf("str is null\n");
ret = 0;
}
else
{
str1 = malloc(strlen(str) + 1);
strcpy(str1, str);
//1.分割字符串
p = strtok(str1, split);
while (p != NULL) {
//2.判断字符串是否为16进制,若为16进制返回10进制,否则直接转换为整型
if (isString_Hex(p))
{
//字符串为16进制,转换为十进制
/* strtol converts string to long integer */
num = strtol(p,NULL, 16);
}
else
{
//字符串为10进制
num = strtol(p, NULL, 10);
}
printf("p:%s ", p);
ip[seg_num] = num;
printf("ip[seg_num]=%ld\n", ip[seg_num]);
seg_num++;
p = strtok(NULL, split);
}
if (seg_num == 4)
{
for (i = 0; i < seg_num; i++)
{
if ((ip[i] >= 0) && (ip[i] <= 255))
correct++;
}
if (correct == 4)
{
ret = 1;
}
else
{
ret = 0;
}
}
else
{
ret = 0;
}
}
return ret;
}
int main()
{
char str[] = "f.e.a.c";
int ret = 0;
ret=checkIP(str);
if (ret == 0)
{
printf("IP 无效\n");
}
else if (ret == 1)
{
printf("IP 有效\n");
}
printf("hello\n");
system("pause");
return 0;
}
运行结果如下:
程序代码分析:
1.ip地址的格式为xx.xx.xx.xx,由3个‘.’隔开,因此,按照字符‘.’分割字符串,分割字符串使用c库函数strtok.
strtok详解:
函数原型:char strtok(char *str,const char * delimiters);
函数功能:
strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串,参数delim则为分割字符串中包含的所有字符。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回指向被分割出片段的指针。
函数参数;
str:在第一次调用时str需要传入被切割字符的首地址,在后面调用时间传入NULL.
delimiter:表示切割字符串(字符串中的每个字符都会当做分割符)。
函数返回值:
从str开头开始的一个个被分割的串。当str中的字符查找到末尾时,返回NULL。
如果查找不到delimiters中的字符时,返回当前strtok的字符串的指针。
所有delim中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。
2.判断每个分割的字符串是否为16进制;
若字符串为16进制,转换为10进制,再转换为整型。
若字符串为10进制,转换为整型,
字符串转换为长整型使用c库函数strtol
long int strtol(const char * nptr,char **endptr,int base);
函数功能:strtol()会将nptr指向的字符串,根据参数base,安全转换为long int,然后返回这个值。
参数base的范围为2-26和0,它决定了字符串以被转换为整数的权值。
可以被转换的合法字符依据base而定,举例来说,当base为2时,合法字符为‘0’,‘1’;base为8时,合法字符 为‘0’,‘1’,……‘7’;base为10时,合法字符为‘0’,‘1’,……‘9’;base 为16时,合法字符为‘0’,‘1’,……‘9’,‘a’, ……‘f’;strtol()函数检测到第一个非法字符时,立即停止检测,其后所有的字符都会被当做非法字符处理。合法的字符 串会转换为long int,作为函数的返回值。非法字符串即从第一个非法字符的地址,被赋给*endptr.**endptr是个双重指针, 即指针的指针。strtol()函数就是通过它改变*endptr的值,即把第一个非法字符的地址传给endptr.
多数情况下,endptr设置为NULL, 即不返回非法字符串。
3.判断分割的子串个数,和字符‘.’的个数
若分割的子串个数为4个,'.'是3个,符合ip规范,且每个子串的10进制数在0-255之间,则输入的ip地址为有效的ip地址;
其他情况的ip均为无效ip.