C语言将点分十进制的IP字符串转成4个整数

最近在做lldp的snmp返回值时需要做这样的转换处理:C语言将点分十进制的IP字符串转成4个整数。

这里用两种方式:

  1. sscanf格式化处理
  2. 用 inet_aton函数将ip字符串转成32位的整形,然后再根据bit转成对应的4个整数。
  • man命令可以确认下sscanf和inet_aton的返回值,以确认处理成功还是失败。
  • 字节序问题:inet_aton后统一用网络字节序,避免出错。

sscanf

#include <stdio.h>// 1 succeed, 0 failed
int parse_ip_sscanf(const char *ip_str, int *a, int *b, int *c, int *d) {return sscanf(ip_str, "%d.%d.%d.%d", a, b, c, d) == 4;
}int main() {// 定义点分十进制的 IP 字符串const char *ip_str = "192.168.1.1";// 定义变量存储解析结果int a, b, c, d;if (0 == parse_ip_sscanf(ip_str, &a, &b, &c, &d)) {printf("parse_ip_sscanf failed\n");} else {printf("parse done: %d %d %d %d\n", a, b, c, d);}return 0;
}

inet_aton + ntol

#include <stdio.h>
#include <arpa/inet.h>#define u8 unsigned char// 1 succeed, 0 failed
int parse_ip_inet_aton(const char *ip_str, int *a, int *b, int *c, int *d) {u8 *p = NULL;in_addr_t ip_int;if (inet_aton(ip_str, (struct in_addr *)&ip_int) == 0) {return 0;  // 解析失败}p = (u8 *)&ip_int;*a = p[0];*b = p[1];*c = p[2];*d = p[3];return 1;  // 解析成功
}int main() {// 定义点分十进制的 IP 字符串const char *ip_str = "192.168.1.1";// 定义变量存储解析结果int a, b, c, d;if (0 == parse_ip_inet_aton(ip_str, &a, &b, &c, &d)) {printf("parse_ip_sscanf failed\n");} else {printf("parse done: %d %d %d %d\n", a, b, c, d);}return 0;
}

哪个效率高点?

这里用的是固定的字符串跑的测试,不太严谨。。。可以考虑随机生成1~255的数字组成ip字符串,然后再跑下测试。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <time.h>#define TEST_COUNT 1000000  // 测试次数// 使用 sscanf 解析 IP 地址
int parse_ip_sscanf(const char *ip_str, int *a, int *b, int *c, int *d) {return sscanf(ip_str, "%d.%d.%d.%d", a, b, c, d) == 4;
}// 使用 inet_aton 解析 IP 地址
int parse_ip_inet_aton(const char *ip_str, int *a, int *b, int *c, int *d) {in_addr_t ip_int;if (inet_aton(ip_str, (struct in_addr *)&ip_int) == 0) {return 0;  // 解析失败}ip_int = ntohl(ip_int);*a = (ip_int >> 24) & 0xFF;*b = (ip_int >> 16) & 0xFF;*c = (ip_int >> 8) & 0xFF;*d = ip_int & 0xFF;return 1;  // 解析成功
}int main() {// 定义点分十进制的 IP 字符串const char *ip_str = "192.168.1.1";// 定义变量存储解析结果int a, b, c, d;// 记录失败的次数int sscanf_fail_count = 0;int inet_aton_fail_count = 0;// 测试 sscanf 方式clock_t start = clock();for (int i = 0; i < TEST_COUNT; i++) {if (0 == parse_ip_sscanf(ip_str, &a, &b, &c, &d)) {sscanf_fail_count++;}}clock_t end = clock();double sscanf_time = (double)(end - start) / CLOCKS_PER_SEC;printf("sscanf 方式耗时: %.6f 秒\n", sscanf_time);printf("sscanf 方式失败次数: %d\n", sscanf_fail_count);// 测试 inet_aton 方式start = clock();for (int i = 0; i < TEST_COUNT; i++) {if (0 == parse_ip_inet_aton(ip_str, &a, &b, &c, &d)) {inet_aton_fail_count++;}}end = clock();double inet_aton_time = (double)(end - start) / CLOCKS_PER_SEC;printf("inet_aton 方式耗时: %.6f 秒\n", inet_aton_time);printf("inet_aton 方式失败次数: %d\n", inet_aton_fail_count);// 比较两种方式的效率if (sscanf_time < inet_aton_time) {printf("sscanf 方式更快,效率高出 %.2f 倍\n", inet_aton_time / sscanf_time);} else {printf("inet_aton 方式更快,效率高出 %.2f 倍\n", sscanf_time / inet_aton_time);}return 0;
}/*
sscanf 方式耗时: 0.104025 秒
sscanf 方式失败次数: 0
inet_aton 方式耗时: 0.027499 秒
inet_aton 方式失败次数: 0
inet_aton 方式更快,效率高出 3.78 倍
*/

修改ip随机生成一百万次,测试:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <time.h>#define TEST_COUNT 1000000  // 测试次数// 生成一个随机的合法 IP 地址字符串
void generate_random_ip(char *ip_str) {sprintf(ip_str, "%d.%d.%d.%d",rand() % 256, rand() % 256, rand() % 256, rand() % 256);
}// 使用 sscanf 解析 IP 地址
int parse_ip_sscanf(const char *ip_str, int *a, int *b, int *c, int *d) {return sscanf(ip_str, "%d.%d.%d.%d", a, b, c, d) == 4;
}// 使用 inet_aton 解析 IP 地址
int parse_ip_inet_aton(const char *ip_str, int *a, int *b, int *c, int *d) {in_addr_t ip_int;if (inet_aton(ip_str, (struct in_addr *)&ip_int) == 0) {return 0;  // 解析失败}ip_int = ntohl(ip_int);*a = (ip_int >> 24) & 0xFF;*b = (ip_int >> 16) & 0xFF;*c = (ip_int >> 8) & 0xFF;*d = ip_int & 0xFF;return 1;  // 解析成功
}int main() {// 初始化随机数种子srand(time(NULL));// 定义变量存储解析结果int a, b, c, d;// 记录失败的次数int sscanf_fail_count = 0;int inet_aton_fail_count = 0;// 动态分配堆空间存储 IP 地址数组char (*ip_array)[16] = malloc(TEST_COUNT * sizeof(*ip_array));if (ip_array == NULL) {printf("内存分配失败!\n");return 1;}// 随机生成 IP 地址数组for (int i = 0; i < TEST_COUNT; i++) {generate_random_ip(ip_array[i]);}// 测试 sscanf 方式clock_t start = clock();for (int i = 0; i < TEST_COUNT; i++) {if (!parse_ip_sscanf(ip_array[i], &a, &b, &c, &d)) {sscanf_fail_count++;}}clock_t end = clock();double sscanf_time = (double)(end - start) / CLOCKS_PER_SEC;printf("sscanf 方式耗时: %.6f 秒\n", sscanf_time);printf("sscanf 方式失败次数: %d\n", sscanf_fail_count);// 测试 inet_aton 方式start = clock();for (int i = 0; i < TEST_COUNT; i++) {if (!parse_ip_inet_aton(ip_array[i], &a, &b, &c, &d)) {inet_aton_fail_count++;}}end = clock();double inet_aton_time = (double)(end - start) / CLOCKS_PER_SEC;printf("inet_aton 方式耗时: %.6f 秒\n", inet_aton_time);printf("inet_aton 方式失败次数: %d\n", inet_aton_fail_count);// 比较两种方式的效率if (sscanf_time < inet_aton_time) {printf("sscanf 方式更快,效率高出 %.2f 倍\n", inet_aton_time / sscanf_time);} else {printf("inet_aton 方式更快,效率高出 %.2f 倍\n", sscanf_time / inet_aton_time);}return 0;
}/*
sscanf 方式耗时: 0.116505 秒
sscanf 方式失败次数: 0
inet_aton 方式耗时: 0.043936 秒
inet_aton 方式失败次数: 0
inet_aton 方式更快,效率高出 2.65 倍
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/66678.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebLogic安全基线

WebLogic安全基线 一、 用户权限1 、检查weblogic 的启动用户2 、用户权限整改3 、使用普通用户重启weblogic 二、账户共用1 、检查weblogic 控制台的账户2 、账户共用整改3 、测试登录weblogic 控制台新账户 三、 账户清理1 、检查weblogic 控制台的账户2 、帐户清理整改 四、…

react-quill 富文本组件编写和应用

index.tsx文件 import React, { useRef, useState } from react; import { Modal, Button } from antd; import RichEditor from ./RichEditor;const AnchorTouchHistory: React.FC () > {const editorRef useRef<any>(null);const [isModalVisible, setIsModalVis…

TDv2:一种用于离线数学表达式识别的新型树形结构解码器

TDv2:一种用于离线数学表达式识别的新型树形结构解码器 本文提出了一种针对手写数学表达式识别(HMER)任务的新型树形解码器(TDv2) ,旨在充分利用数学表达式的树结构标签进行更有效的建模和预测。相较于传统的LaTeX字符串解码器,该模型通过采用一个节点分类模块和一个分…

银行信贷管理系统flask

完整源码项目包获取→点击文章末尾名片&#xff01;

WordPress静态缓存插件WP Super Cache与 WP Fastest Cache

引言 WordPress是一款开源的内容管理系统&#xff08;CMS&#xff09;&#xff0c;最初作为博客平台开发&#xff0c;现已发展成为一个功能强大的建站工具&#xff0c;支持创建各种类型的网站&#xff0c;包括企业网站、在线商店、个人博客等。它具有用户友好的界面、丰富的插…

onLoad 生命周期函数是否执行取决于跳转的方式和小程序的页面栈管理机制

文章目录 1. 页面跳转方式2. 你的场景分析3. 页面生命周期4. 总结5. 建议 在微信小程序中&#xff0c;页面跳转时&#xff0c; onLoad 生命周期函数是否执行取决于跳转的方式和小程序的页面栈管理机制。以下是详细说明&#xff1a; 1. 页面跳转方式 微信小程序提供了多种页面…

【深度学习】通俗理解偏差(Bias)与方差(Variance)

在统计学习中&#xff0c;我们通常使用方差与偏差来衡量一个模型 1. 方差与偏差的概念 偏差(Bais)&#xff1a; 预测值和真实值之间的误差 方差(Variance)&#xff1a; 预测值之间的离散程度 低偏差低方差、高偏差低方差&#xff1a; 图中每个点表示同一个模型每次采样出不同…

生态水文研究中的机器学习与数学建模方法选择

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【LeetCode】力扣刷题热题100道(21-25题)附源码 接雨水 合并区间 字母异位词 滑动窗口 覆盖子串(C++)

目录 1.接雨水 2.合井区间 3.找到字符串中所有字母异位词 4.滑动窗口最大值 5.最小覆盖子串 1.接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 代码如下所示&#xff1a; class Solution {…

慧集通(DataLinkX)iPaaS集成平台-智能体(Agent)API

功能简介&#xff1a; 该功能下主要是用来管理集成平台对外开放接口得管控以及调用日志信息得查看操作&#xff0c;并支持日志得重放等操作&#xff1b;注&#xff1a;所有触发类单据得日志也可以在此查看(如使用数据触发组件自动触发流程得日志信息) 1.第三方调用接口类日志查…

HTB:Bank[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 提取出靶机TCP开放端口 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用curl对域名进行访问…

创建基本的 Electron 应用项目的详细步骤

创建一个基本的 Electron 应用项目的详细步骤。我们将从安装 Node.js 开始&#xff0c;然后创建项目文件夹并初始化 Electron 项目。 1. 安装 Node.js 首先&#xff0c;确保你已经安装了 Node.js 和 npm。你可以在终端中运行以下命令来检查是否已经安装&#xff1a; node -v…

TDengine + MQTT :车联网时序数据库如何高效接入

现代新能源汽车&#xff0c;作为一种内部系统极为复杂的交通工具&#xff0c;配备了大量传感器、导航设备、应用软件&#xff0c;这些传感器产生的数据都需要上报到车联网平台当中。对于这些车辆的状态数据&#xff08;如车速、发动机转速等&#xff09;、位置数据&#xff08;…

2. Scala 高阶语法之集合与元组

背景 上一章简单介绍了scala是什么&#xff0c;以及scala的基础用法&#xff0c;本文介绍scala的高阶语法&#xff0c;希望看完本章之后&#xff0c;读者能体会到scala和java的明显区别&#xff0c;以及scala的强大之处。 1. 数组 Scala中提供了一种数据结构-数组&#xff0…

初学STM32 --- USMART

目录 USMART简介 USMART主要特点&#xff1a; USMART原理 USMART组成&#xff1a; USMART 的实现流程简单概括 USMART扫描函数&#xff1a; USMART系统命令 USMART移植 USMART简介 USMART是一个串口调试组件&#xff0c;可以大大提高代码调试效率&#xff01; USMART主…

SQL编程语言

第一章 1. 数据库是长期储存在计算机内&#xff0c;由专门的数据管理软件(数据库管理系统)&#xff0c;进行统一组织和管理控制的大量数据的集合。 2.数据库的基本特点不包括可以快速检索。 3. 数据管理技术的发展经历了&#xff1a;人工管理阶段、文件系统阶段、数据库系统阶…

机器学习周报-ModernTCN文献阅读

文章目录 摘要Abstract 0 提升有效感受野&#xff08;ERF&#xff09;1 相关知识1.1 标准卷积1.2 深度分离卷积&#xff08;Depthwise Convolution&#xff0c;DWConv&#xff09;1.3 逐点卷积&#xff08;Pointwise Convolution&#xff0c;PWConv&#xff09;1.4 组卷积(Grou…

《OpenCV计算机视觉实战项目》——银行卡号识别

文章目录 项目任务及要求项目实现思路项目实现及代码导入模块设置参数对模版图像中数字的定位处理银行卡的图像处理读取输入图像&#xff0c;预处理找到数字边框使用模版匹配&#xff0c;计算匹配得分 画出并打印结果 项目任务及要求 任务书&#xff1a; 要为某家银行设计一套…

【LeetCode: 560. 和为 K 的子数组 + 前缀和 + 哈希表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Tableau数据可视化与仪表盘搭建-可视化原则及BI仪表盘搭建

目录 可视化原则 BI仪表盘搭建 仪表盘搭建原则 明确仪表盘主题 仪表盘主题拆解 开发设计工作表 经营情况总览&#xff1a;突出显示的文字 经营数据详情&#xff1a;表格 每日营收数据&#xff1a;多轴折线图 每日流量数据&#xff1a;双轴组合图 新老客占比&#xf…