利用C語言將點(diǎn)分十進(jìn)制的IP字符串轉(zhuǎn)成4個(gè)整數(shù)
最近在做lldp的snmp返回值時(shí)需要做這樣的轉(zhuǎn)換處理:C語言將點(diǎn)分十進(jìn)制的IP字符串轉(zhuǎn)成4個(gè)整數(shù)。
這里用兩種方式:
1.sscanf格式化處理
2.用 inet_aton函數(shù)將ip字符串轉(zhuǎn)成32位的整形,然后再根據(jù)bit轉(zhuǎn)成對(duì)應(yīng)的4個(gè)整數(shù)。
man命令可以確認(rèn)下sscanf和inet_aton的返回值,以確認(rèn)處理成功還是失敗。
字節(jié)序問題:inet_aton后統(tǒng)一用網(wǎng)絡(luò)字節(jié)序,避免出錯(cuò)。
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() {
// 定義點(diǎn)分十進(jìn)制的 IP 字符串
const char *ip_str = "192.168.1.1";
// 定義變量存儲(chǔ)解析結(jié)果
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() {
// 定義點(diǎn)分十進(jìn)制的 IP 字符串
const char *ip_str = "192.168.1.1";
// 定義變量存儲(chǔ)解析結(jié)果
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;
}
哪個(gè)效率高點(diǎn)?
這里用的是固定的字符串跑的測試,不太嚴(yán)謹(jǐn)。。。可以考慮隨機(jī)生成1~255的數(shù)字組成ip字符串,然后再跑下測試。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <time.h>
#define TEST_COUNT 1000000 // 測試次數(shù)
// 使用 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() {
// 定義點(diǎn)分十進(jìn)制的 IP 字符串
const char *ip_str = "192.168.1.1";
// 定義變量存儲(chǔ)解析結(jié)果
int a, b, c, d;
// 記錄失敗的次數(shù)
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 方式耗時(shí): %.6f 秒\n", sscanf_time);
printf("sscanf 方式失敗次數(shù): %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 方式耗時(shí): %.6f 秒\n", inet_aton_time);
printf("inet_aton 方式失敗次數(shù): %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 方式耗時(shí): 0.104025 秒
sscanf 方式失敗次數(shù): 0
inet_aton 方式耗時(shí): 0.027499 秒
inet_aton 方式失敗次數(shù): 0
inet_aton 方式更快,效率高出 3.78 倍
*/
修改ip隨機(jī)生成一百萬次,測試:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <time.h>
#define TEST_COUNT 1000000 // 測試次數(shù)
// 生成一個(gè)隨機(jī)的合法 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() {
// 初始化隨機(jī)數(shù)種子
srand(time(NULL));
// 定義變量存儲(chǔ)解析結(jié)果
int a, b, c, d;
// 記錄失敗的次數(shù)
int sscanf_fail_count = 0;
int inet_aton_fail_count = 0;
// 動(dòng)態(tài)分配堆空間存儲(chǔ) IP 地址數(shù)組
char (*ip_array)[16] = malloc(TEST_COUNT * sizeof(*ip_array));
if (ip_array == NULL) {
printf("內(nèi)存分配失敗!\n");
return 1;
}
// 隨機(jī)生成 IP 地址數(shù)組
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 方式耗時(shí): %.6f 秒\n", sscanf_time);
printf("sscanf 方式失敗次數(shù): %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 方式耗時(shí): %.6f 秒\n", inet_aton_time);
printf("inet_aton 方式失敗次數(shù): %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 方式耗時(shí): 0.116505 秒
sscanf 方式失敗次數(shù): 0
inet_aton 方式耗時(shí): 0.043936 秒
inet_aton 方式失敗次數(shù): 0
inet_aton 方式更快,效率高出 2.65 倍
*/
以上就是利用C語言將點(diǎn)分十進(jìn)制的IP字符串轉(zhuǎn)成4個(gè)整數(shù)的詳細(xì)內(nèi)容,更多關(guān)于C語言IP字符串轉(zhuǎn)成4個(gè)整數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
QT中start()和startTimer()的區(qū)別小結(jié)
QTimer提供了定時(shí)器信號(hào)和單觸發(fā)定時(shí)器,本文主要介紹了QT中start()和startTimer()的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-09-09
一文帶你了解C語言中的動(dòng)態(tài)內(nèi)存管理函數(shù)
C語言中內(nèi)存管理相關(guān)的函數(shù)主要有realloc、calloc、malloc、free等,這篇文章主要為大家講解一下這四個(gè)函數(shù)的具體用法,需要的可以參考一下2023-03-03
詳解C/C++ QT QChart 繪制組件應(yīng)用
Qtcharts 組件基于GraphicsView模式實(shí)現(xiàn),其核心是QChartView和QChart的二次封裝版。本文重點(diǎn)給大家介紹C/C++ QT QChart 繪制組件應(yīng)用的相關(guān)知識(shí),感興趣的朋友一起看看吧2021-11-11

