相信大家都见过这样一个情况:在输入框输入ip地址的过程中,如果输入错误,UI就会弹框提示你输入有误。比如当你输入1926、192… 、192.168.6.8.6等等错误的数据,都会提示你输入错误。接下来用C语言来判断输入ip的过程中是不是正确的输入,主要是判断以下几种情况是不合法的:
1、同时出现两个小数点或者以小数点开头
2、输入的小数点大于3
3、小数点之间的数字不在0~255之间
//把str字符串中,第一个end字符出现的左边字符串放到out_buf中
char* str_substring_left(const char* str, char end, char* out_buf, int out_buf_len)
{
int flag = 0;
char* s = out_buf;
memset(s, 0, out_buf_len);
__ast(str);
while(*str)
{
if(*str == end)
{
break;
}
else if(flag >= 0 && flag < (out_buf_len - 1))
{
s[flag++] = *str;
}
str++;
}
return s;
}
//校验输入过程中的ip 是否合法,比如(192.16)
int check_input_ip_valid(const char* ip)
{
int i = 0;
const char* tmp = NULL;
int value = 0;
tmp = ip;
while(strchr(tmp,'.') != NULL)
{
char str[5] = {0};
i++;
if(tmp[0] == '.')//两个小数点或者以小数点开头了
{
printf("%s,started by '.' or '..' appear !\n",__func__);
return -1;
}
if(i > 3)//大于了4 段
{
printf("%s,segment > 3 , not support ! \n",__func__);
return -2;
}
str_substring_left(tmp, '.', str, sizeof(str));
value = atoi(str);
if(value < 0 || value > 255)
{
printf("%s,value is not in 0 ~ 255 !\n",__func__);
return -3;
}
tmp = strchr(tmp,'.') + 1;
}
if(tmp != NULL)//最后一段或者没有小数点的校验
{
value = atoi(tmp);
if(value < 0 || value > 255)
{
printf("%s,value is not in 0 ~ 255!\n",__func__);
return -3;
}
}
return 1; //校验成功
}
还有一个判断是,判断完整的ip是否是合法的。
//判断最终输入的ip是不是合法可以保存的(比如192.168.8.125是合法的,192.168.8是不合法的)
int str_is_ip(char *str)
{
struct in_addr addr;
int ret;
ret = inet_pton(AF_INET, str, &addr);
if(ret > 0)
{
printf("%s is a valid IPv4 address\n", str);
}
else if(ret < 0)
{
printf("%s EAFNOSUPPORT!\n", __func__);
}
else
{
printf("%s is not a valid IPv4 address\n", str);
}
return ret;
}
或者可以通过C语言的正则表达式来判断,先说两个写好的正则表达式字符串:
1、判断输入过程中的ip:
^(((2(5[0-5])|[0-4][0-9])|(1?[0-9]{1,2})).){0,3}((2(5[0-5])|[0-4][0-9])|(1?[0-9]{1,2}))?$
2、判断最终的ip是否合法:
^(((2(5[0-5])|[0-4][0-9])|(1?[0-9]{1,2})).){3}((2(5[0-5])|[0-4][0-9])|(1?[0-9]{1,2}))$
然后是一个写好的正则匹配的接口,如下面的match函数,举例如下:
#include <stdio.h>
#include <sys/types.h>
#include <regex.h>
#include <memory.h>
#include <stdlib.h>
int match(char *_string, char *_pattern)
{
int rv = -1;
regex_t *p_re = NULL;
char buf[256] = {0};
p_re = calloc(1, sizeof(regex_t));
if (p_re == NULL)
{
//printf("error: calloc: %d\n", errno);
rv = -1;
goto _end;
}
rv = regcomp(p_re, _pattern, REG_EXTENDED|REG_NOSUB);
if (rv != 0)
{
(void)regerror(rv, p_re, buf, sizeof buf);
printf("error: regcomp: %s\n",buf);
goto _end;
}
rv = regexec(p_re, _string, (size_t)0, NULL, 0);
regfree(p_re);
if (rv != 0)
{
(void)regerror(rv, p_re, buf, sizeof buf);
printf("regexec: %s, [%d],[%s]\n", buf, rv, _pattern);
goto _end;
}
rv = 0;
_end:
if (p_re != NULL)
{
free(p_re);
}
return rv;
} // match
int main(int argc,char* argv[])
{
int ret = -1;
printf(".00000000000\n");
char* ip_str = argv[1];
printf("ip_str = %s\n",ip_str);
char* pattern = "^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])$";
//char *pattern = "^(((2(5[0-5])|[0-4][0-9])|(1?[0-9]{1,2}))\\.){3}((2(5[0-5])|[0-4][0-9])|(1?[0-9]{1,2}))$"; //两个正则表达式都可以用
ret = match(ip_str, pattern);
if(ret == 0)
{
printf("match %s\n",ip_str);
}
else
{
printf("no match!\n");
}
return 0;
}