C语言将点分十进制的IP字符串转成4个整数
最近在做lldp的snmp返回值时需要做这样的转换处理:C语言将点分十进制的IP字符串转成4个整数。
这里用两种方式:
- sscanf格式化处理
- 用 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 倍
*/
相关文章:
C语言将点分十进制的IP字符串转成4个整数
最近在做lldp的snmp返回值时需要做这样的转换处理:C语言将点分十进制的IP字符串转成4个整数。 这里用两种方式: sscanf格式化处理用 inet_aton函数将ip字符串转成32位的整形,然后再根据bit转成对应的4个整数。 man命令可以确认下sscanf和i…...
go语言学习 笔记 1(变量,语法,数据类型)
1,包管理 一个文件夹可以称为一个包 在一个包里面可以创建多个文件 包中可以创建包 同一个包内的同一级的包的名字要相同 如:包a中的包b.包b中的包得是同一个package,a中和包b同级的包名字也得是一个名字 必须要有一个main包,入口,就像是c必须有一个main函数 如果没有mai…...
无网络时自动切换备用网络环境
目录 背景目标为什么需要做自动网络切换网络切换手段 网络环境实现思路和代码部署脚本开机自动执行附录连接两个网络时的路由问题 背景 目标 学校实验室有两个网络环境,我电脑使用网线连接稳定但低速的网络A,使用WiFi连接高速但不稳定的网络B。因此&am…...
电脑32位和64位之区别(Difference between 32-Bit and 64 Bit Computers)
电脑32位和64位之区别 很多小伙伴还不知道电脑32位和64位是什么意思,今天小编就来普及一下。 32位和64位是指电脑处理器(CPU)和操作系统的架构,决定了电脑如何处理数据、存储信息、运行程序等。 32位和64位是指电脑系统中每个处…...
系统思考—结构影响行为
前段时间,我遇到了一位健康食品初创公司的创始人,产品质量毋庸置疑,但销量却始终打不开局面,资金链也日渐紧绷。他一脸困惑地问我:“我们已经尽力了,为什么结果还是不如人意?”经过深入交流&…...
【算法不挂科】算法期末考试【选择题专项练习】<多单元汇总>
前言 大家好吖,欢迎来到 YY 滴算法不挂科系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 下面是相关传送门 【算法不挂科】算法期末考试题库1(带解析)【选择题53道&填空题36道&算法填空题7道&a…...
2025.1.8(c++对c语言的扩充——堆区空间,引用,函数)
笔记 上一笔记接续(练习2的答案) 练习:要求在堆区连续申请5个int的大小空间用于存储5名学生的成绩,分别完成空间的申请、成绩的录入、升序排序、成绩输出函数以及空间释放函数,并在主程序中完成测试 要求使用new和d…...
如何将Yum源修改为本地挂载的ISO镜像
要将yum源修改为本地挂载的ISO镜像,您可以按照以下步骤进行操作。假设您使用的是CentOS或类似的基于Red Hat的Linux发行版,且已经将ISO镜像文件挂载到系统中。 步骤一:挂载ISO镜像 创建一个挂载点: 首先,您需要创建一个目录来作为ISO镜像的挂载点。例如: sudo mkdir /mnt…...
salesforce如何在系统里保存密码
在 Salesforce 中,保存密码或类似敏感信息时,不应以明文形式存储,而应采用安全的加密和存储机制。以下是一些最佳实践和实现方法: 1. 使用 Salesforce 提供的加密机制 Salesforce 提供了一些内置的加密工具,可以用来加…...
函数提升+上下文+内存清理及释放
文章目录 函数提升上下文函数释放拓展-垃圾回收机制垃圾回收之触发应用 函数提升上下文 函数提升(Hoisting) 概念:在JavaScript中,函数声明会被提升到当前作用域的顶部。这意味着可以在函数声明之前调用函数。例如: sa…...
计算机网络之---计算机网络的性能评估
计算机网络的性能评估是指通过各种标准和指标来衡量网络的工作效率和质量,进而对网络进行优化和改进的过程。评估的目标是确保网络能够满足预期的服务质量(QoS)和性能需求。常见的计算机网络性能评估指标包括带宽、延迟、吞吐量、丢包率等。 …...
Unity学习之UGUI进阶
一、事件监听接口 1、作用 用于实现类型长按、双击、拖拽等基础控件无法实现的功能 所有控件都能够添加更多的事件监听来处理对应的逻辑 2、事件监听接口类型 (1)常用事件接口 (2)不常用事件接口 3、使用事件监听接口 &#…...
深度学习领域创新黑马!频域特征融合新突破
最近,FreqFusion引起了广泛关注,这是一种创新的频率感知特征融合方法,可以提升数据处理的准确性和效率,尤其在语义分割、目标检测、实例分割和全景分割等任务中表现卓越。 通过结合频域分析与特征融合技术,FreqFusion…...
路由器的转发表
【4-24】 已知路由器R₁ 的转发表如表T-4-24 所示。 表T-4-24 习题4-24中路由器R₁的转发表 前缀匹配 下一跳地址 路由器接口 140.5.12.64/26 180.15.2.5 m2 130.5.8/24 190.16.6.2 ml 110.71/16 ----- m0 180.15/16 ----- m2 190.16/16 ----- ml 默认 11…...
用Cline打造你的智能搜索助手:Tavily Search MCP集成指南
引言 本文将详细介绍如何在Cline编辑器中集成Tavily Search智能搜索功能。我们将从MCP(Model Context Protocol)协议基础开始,深入探讨Tavily Search MCP服务器的安装配置、使用方法,以及进阶的二次开发技巧。无论你是AI开发者还…...
HTML+CSS+JS制作中华传统美食主题网站(内附源码,含5个页面)
一、作品介绍 HTMLCSSJS制作一个中华传统文化主题网站,包含首页、菜系页、食材页、名厨页、美食故事页等5个静态页面。其中每个页面都包含一个导航栏、一个主要区域和一个底部区域。 二、页面结构 1. 顶部横幅导航区 包含网站Logo、搜索栏、主导航菜单࿰…...
黄仁勋CES 2025演讲重点内容
黄仁勋CES 2025演讲重点内容 硬件产品发布 GeForce RTX 50系列GPU: 架构与性能提升:正式发布的新一代GeForce RTX 50系列GPU采用英伟达旗舰的Blackwell架构,这是自25年前引入可编程着色技术以来计算机图形领域最重大的创新。该系列显卡在图形…...
TVbox 手机、智能电视节目一网打尽
文章目录 一、简要介绍二、优点三、下载地址 一、简要介绍 TVbox是目前最火爆的多端、多源的电视影音工具,是一款开源的自定义添加站源的影音工具。TVBox,支持电视频道直播。一款TV端影视工具,软件本身不具有任何影视资源,但可以…...
sys.dm_exec_connections:查询与 SQL Server 实例建立的连接有关的信息以及每个连接的详细信息(客户端ip)
文章目录 引言I 基于dm_exec_connections查询客户端ip权限物理联接时间范围dm_exec_connections表see also: 监视SQL Server 内存使用量资源信号灯 DMV sys.dm_exec_query_resource_semaphores( 确定查询执行内存的等待)引言 查询历史数据库客户端ip应用场景: 安全分析缺乏…...
kubesphere前端源码运行
一、下载源码 源码是react,下载地址是 GitHub - kubesphere/console at v3.3.2 然后直接用git下拉就可以了 下拉完成后差不多是这样一个目录结构,记得切分支到3.3.2 二、下载依赖 1、node & yurn 想要运行源码首先需要node,使用刚才…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
