C语言编程实现对IPV4地址的合法性判断(使用正则表达式)

有了解过我的朋友,可能有点印象,我在N年前的博客中,就写了这个主题,当时确实是工作中遇到了这个问题。本想着等工作搞完之后,就把这个问题的解决代码补上,结果一鸽,就是好几年,真是惭愧。现在把这部分代码公开,欢迎大家来下载测试。

文章目录

  • 1 写在前面
  • 2 什么是正则表达式
  • 3 需求分析
  • 4 C语言版本(正则表达式)
  • 5 完整测试用例

1 写在前面

之前我写过一篇博文,主要介绍如何使用C语言编程实现对IPV4地址的合法性进行判断,不过那次我使用的原生的C语言函数来实现的,本篇博文将给大家介绍一下,如何在C语言编程的环境下,使用正则表达式完成这个功能需求。

2 什么是正则表达式

正则表达式是一种用于匹配文本模式的工具,它可以通过一些特定的字符和语法规则来描述一个文本模式,并在文本中查找符合该模式的字符串。正则表达式可以用于文本搜索、替换、验证等多种应用场景,是程序员和文本处理工作者必备的工具之一。

正则表达式,在一些高级编程语言中,都有成熟的库接口来调用,而在C语言中,却鲜有这样的例子。但并不是说它不能用,其实它也是可以用的。

在C语言中使用正则表达式时,有一些注意事项需要注意:

  1. 首先需要包含regex.h头文件。
  2. 在使用正则表达式之前,需要使用regcomp()函数将正则表达式编译成一个模式。
  3. 在使用regexec()函数执行正则表达式时,可以使用REG_EXTENDED选项来启用扩展正则表达式,或使用REG_ICASE选项来忽略大小写。
  4. 在使用regexec()函数时,如果返回值为0,表示匹配成功;如果返回值为REG_NOMATCH,表示没有匹配成功;如果返回值为其他值,表示发生了错误。
  5. 在使用regerror()函数获取错误信息时,需要提供一个缓冲区和缓冲区大小。
  6. 在使用完正则表达式后,需要使用regfree()函数释放编译后的模式。
  7. 正则表达式中的特殊字符需要进行转义,例如.需要写成\.,否则它将匹配任何字符。
  8. 正则表达式中的括号可以用于分组,例如([0-9]{1,3}\.){3}[0-9]{1,3}可以匹配一个IP地址。
  9. 在使用正则表达式时,需要注意性能问题,因为正则表达式匹配可能会消耗大量的CPU资源。可以考虑使用更简单的字符串匹配算法,例如strstr()函数。

更多关于正则表达式的介绍,可以参考:正则表达式语言 - 快速参考 | Microsoft Learn

3 需求分析

其实,本专题的需求很简单,就是输入一段字符串,判断它是不是合法的IPv4地址。仅仅从功能上看,似乎很简单,但是真正要做到很完美,也是需要下点功夫的。不信,你看看下文的拆解。

4 C语言版本(正则表达式)

我们先上一个简单版本,直接看代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>#include <regex.h>static int is_valid_ipv4_regex(const char *ip_address)
{regex_t regex;int reti;// Compile regular expressionreti = regcomp(&regex, "^([0-9]{1,3}\\.){3}[0-9]{1,3}$", REG_EXTENDED);if (reti) {fprintf(stderr, "Could not compile regex\n");reti = 0;}// Execute regular expressionprintf("%s\n", ip_address);reti = regexec(&regex, ip_address, 0, NULL, 0);if (!reti) {printf("Valid IP address %d\n", reti);reti = 1;} else if (reti == REG_NOMATCH) {printf("Invalid IP address xxx %d\n", reti);reti = 0;} else {char error_message[100];regerror(reti, &regex, error_message, sizeof(error_message));fprintf(stderr, "Regex match failed: %s\n", error_message);reti = 0;}exit_entry:// Free compiled regular expressionregfree(&regex);return reti;
}int is_valid_ipv4(const char *ip_address)
{int num, dots = 0;char *ptr;if (ip_address == NULL) {return 0;}ptr = strtok((char *)ip_address, ".");if (ptr == NULL) {return 0;}while (ptr) {if (!isdigit(*ptr)) {return 0;}if (*ptr == '0') { //check start '0'return 0;}num = atoi(ptr);if (num < 0 || num > 255) {return 0;}ptr = strtok(NULL, ".");if (ptr != NULL) {dots++;}}if (dots != 3) {return 0;}if (atoi(ip_address) >= 1 && atoi(ip_address) <= 126) {printf("This is a Class A IP address.\n");return 1;} else if (atoi(ip_address) >= 128 && atoi(ip_address) <= 191) {printf("This is a Class B IP address.\n");return 1;} else if (atoi(ip_address) >= 192 && atoi(ip_address) <= 223) {printf("This is a Class C IP address.\n");return 1;} else {printf("This is not a Class A, B, or C IP address.\n");return 0;}return 1;
}int check_is_valid_ipv4(const char *ip)
{int ret = 0;//ret = is_valid_ipv4(ip); ret = is_valid_ipv4_regex(ip); return ret;
}int main(int argc, const char *argv[])
{const char *ip = argv[1];printf("check %s\n", ip);printf("ret %d\n", check_is_valid_ipv4(ip));
}

编译运行一下,输入一个常见的ipv4地址是没有问题,比如 “192.168.0.1”;同时,非法的字符输入也是会报错的。

recan@ubuntu:~$
recan@ubuntu:~$
recan@ubuntu:~$ ./test 192.168.1.3
check 192.168.1.3
192.168.1.3
Valid IP address 0
ret 1
recan@ubuntu:~$ ./test 192.168.1.t
check 192.168.1.t
192.168.1.t
Invalid IP address xxx 1
ret 0
recan@ubuntu:~$
recan@ubuntu:~$ ./test 192.168.1.oo
check 192.168.1.oo
192.168.1.oo
Invalid IP address xxx 1
ret 0
recan@ubuntu:~$
recan@ubuntu:~$ ./test 192.168.01.8
check 192.168.01.8
192.168.01.8
Valid IP address 0
ret 1
recan@ubuntu:~$
recan@ubuntu:~$

但是细心的朋友可能互发现,当IP地址某一段带前导0时,貌似也会判断为正确的IP地址,而实际上我们一般不会这样写。

那么如何才能规避掉这种情况呢?

有没有可能通过正则表达式来完成呢?

这个问题留给读者自行去探索,是个非常有趣的正则表达式学习。

只要完成了这个功能,相信一定能够让你对正则表达式掌握得更加深入。

5 完整测试用例

本小节给大家补充一下各种测试用例,希望对大家测试代码有帮助:

合法的测试输入
192.168.0.1
10.0.0.1
172.16.0.1
255.255.255.255非法的测试输入
256.0.0.1
192.168.0.0.1
192.168.0
192.168.0.1.2非法的测试输入
256.0.0.1
192.168.0.0.1
192.168.0
192.168.0.1.2
300.300.300.300
1.2.3
1.2.3.4.5
1.2.3.4.
.1.2.3.4
1..2.3.4

测试用例是不断丰富的,欢迎大家来补充。

【偏门技巧】C语言编程实现对IPV4地址的合法性判断(使用正则表达式)相关推荐

  1. 求最大公约数c语言实验心得,C语言编程实训报告(合集)

    cout< void main()//主函数主函数主函数主函数 { int i,g; studentstu[3];while (i){i=menu(stu,3); switch(i) {case ...

  2. 共阳极数码管动态扫描c语言,《C语言编程实训》实训指导书三

    1 C 语言编程实训语言编程实训 实训指导书三实训指导书三 适应专业 应用电子技术适应专业 应用电子技术 广州康大职业技术学院自动化系广州康大职业技术学院自动化系 二二 0 一一 0 年十一月年十一月 ...

  3. 按照题目打印菜单c语言,--单片机C语言编程实训

    实 习 报 告 实习地点:201机房 实习时间:2014.12.1--2014.12.6 实习项目:单片机C语言编程实训 指导老师:骆 乐 姓 名: 班 级:电信3121 一. 实习内容 1.计算字符 ...

  4. C语言编程实训企业计算,C语言编程项目实训

    24.C语言编程项目实训(高级)(全日制一个半月,夜班三个月,学费1390元) 理论与实操一体化课程: 一.C语言基础:1.应用C语言的各种特点:2.应用算法的含义.特点.表示方法 二.C的基本数据类 ...

  5. 利用Matlab编程实现对NetCDF数据针对某一坐标按时间提取风、流、水蒸气等变量信息

    一.NetCDF数据介绍 NetCDF(network Common Data Form)网络通用数据格式是由美国大学大气研究协会(University Corporation for Atmosph ...

  6. 二进制转换为十进制c语言编程,将二进制IP地址转换成十进制(C语言程序实现)

    将二进制IP地址转换成十进制(C语言程序实现) /* * Name: IP Address * Funcion: To convert binary numbers to decimal number ...

  7. c语言判断x的个位数是否为5,用C语言编程从键盘输入一个正整数,判断其个位数是否为5,若是5则输出“yes”,否则输出“no”...

    #include int main(){ int five; printf("输入一个整数:"); scanf("%d",&five); while(f ...

  8. c语言怎样调取网卡信息,求C语言编程实现获取网卡地址

    满意答案 aafsa1266a啊 2013.04.03 采纳率:40%    等级:12 已帮助:6295人 调用 API GetAdaptersInfo 获取本机适配器信息 名称,IP地址,子网掩码 ...

  9. 大牛们的C语言编程建议和技巧!

    点击上方"大鱼机器人",选择"置顶/星标公众号" 福利干货,第一时间送达! 我们鼓励在编程时应有清晰的哲学思维,而不是给予硬性规则.我并不希望你们能认可所有的东 ...

最新文章

  1. mininet报错解决:Exception: Could not find a default OpenFlow controller和Cannot find required executable
  2. 【转】mysqldump的锁表的问题
  3. 打造炫酷通用的ViewPager指示器 Adapter模式适配所有 1
  4. mapgis明码文件转为点线面文件_干货|MAPGIS的二十一个实用方法及技巧
  5. Entity Framework 5.0基础系列
  6. Vue2.x源码学习笔记-Vue实例的属性和方法整理
  7. Tensorflow学习教程------tensorboard网络运行和可视化
  8. 从四个问题透析Linux下C++编译链接
  9. 什么是HTML5前端开发?HTML5前端要学哪些技术?
  10. selenium python怎么断言_如何为python / selenium中的特定元素断言文本?
  11. python零基础能学吗-零基础小白多久能学会python
  12. MVN TEST指定运行脚本
  13. QuartusII-项目工程的功能仿真
  14. Stata:数据包络分析(DEA)
  15. 走进小作坊(二十)----商道:胡雪岩叱咤商场的经营智慧
  16. 男人必备!泡妞全攻略
  17. 批量进行数字变下标的处理
  18. 小米手机销量是乐视的几十倍,为什么雷军还要去跟贾跃亭打口水战?
  19. 浙江咪咕MGV3200_KLH_国科GK6323_2+8_免拆机卡刷固件包
  20. sm-crypto配合hutool加解密报pad block corrupted错误

热门文章

  1. Mari 头部贴图最终效果
  2. java等差数列求和递归_[编程题] 递归实现等差数列–招银面试题1
  3. [技术交流] AutoCAD使用总结
  4. SEO咨询电话每天过百从侧面反映SEO行业前景仍旧一片大好
  5. 两个串口之间传输文件
  6. 学习微表情作用可大了
  7. wifi改装无线打印服务器,wifi打印服务器方案定制USB共享打印机模块定制
  8. c4d python使用方法_C4D Python语言代码编程教程 Cineversity - Introduction to Python in C4D | 龋齿一号GFXCamp...
  9. 小黑迷茫抑郁中的leetcode之旅:19. 删除链表的倒数第 N 个结点
  10. C # FileStream文件流