SoFunction
Updated on 2025-04-14

Use C language to convert dotted decimal IP string into 4 integers

Recently, when doing the snmp return value of lldp, I need to do this conversion process: C language converts dotted decimal IP string into 4 integers.

There are two ways here:

Format processing

2. Use the inet_aton function to convert the ip string into a 32-bit plastic, and then convert it into the corresponding 4 integers according to the bit.

The man command can confirm the return values ​​of sscanf and inet_aton to confirm whether the processing is successful or failed.

Byte order problem: After inet_aton, network byte order is used uniformly to avoid errors.

sscanf

#include <>

// 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() {
    // Define dotted decimal IP string    const char *ip_str = "192.168.1.1";

    // Define variable storage analysis results    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 <>
#include <arpa/>

#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;  // parsing failed    }
    p = (u8 *)&ip_int;
    *a = p[0];
    *b = p[1];
    *c = p[2];
    *d = p[3];
    return 1;  // The analysis is successful}

int main() {
    // Define dotted decimal IP string    const char *ip_str = "192.168.1.1";

    // Define variable storage analysis results    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;
}

Which one is more efficient?

Here we use a fixed string run test, which is not very rigorous. . . You can consider randomly generating 1~255 numbers to form an ip string, and then run the test.

#include <>
#include <>
#include <>
#include <arpa/>
#include <>

#define TEST_COUNT 1000000 // Number of tests
// Use sscanf to resolve IP addressesint 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;
}

// Use inet_aton to resolve IP addressesint 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;  // parsing failed    }
    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;  // The analysis is successful}

int main() {
    // Define dotted decimal IP string    const char *ip_str = "192.168.1.1";

    // Define variable storage analysis results    int a, b, c, d;

    // Number of failed records    int sscanf_fail_count = 0;
    int inet_aton_fail_count = 0;

    // Test sscanf method    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 method takes time: %.6f seconds\n", sscanf_time);
    printf("Sscanf method failed: %d\n", sscanf_fail_count);

    // Test inet_aton method    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 method takes time: %.6f seconds\n", inet_aton_time);
    printf("inet_aton method failed: %d\n", inet_aton_fail_count);

    // Compare the efficiency of the two methods    if (sscanf_time < inet_aton_time) {
        printf("sscanf method is faster and is % %.2f times more efficient\n", inet_aton_time / sscanf_time);
    } else {
        printf("inet_aton method is faster and is %.2f times more efficient\n", sscanf_time / inet_aton_time);
    }

    return 0;
}

/*
 sscanf method takes time: 0.104025 seconds
 sscanf method failed: 0
 inet_aton method takes time: 0.027499 seconds
 Inet_aton method failures: 0
 Inet_aton method is faster and 3.78 times more efficient
 */

Modify the IP to generate one million random times, test:

#include <>
#include <>
#include <>
#include <arpa/>
#include <>

#define TEST_COUNT 1000000 // Number of tests
// Generate a random legal IP address stringvoid generate_random_ip(char *ip_str) {
    sprintf(ip_str, "%d.%d.%d.%d",
            rand() % 256, rand() % 256, rand() % 256, rand() % 256);
}

// Use sscanf to resolve IP addressesint 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;
}

// Use inet_aton to resolve IP addressesint 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;  // parsing failed    }
    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;  // The analysis is successful}

int main() {
    // Initialize random number seeds    srand(time(NULL));

    // Define variable storage analysis results    int a, b, c, d;

    // Number of failed records    int sscanf_fail_count = 0;
    int inet_aton_fail_count = 0;

    // Dynamically allocate heap space storage IP address array    char (*ip_array)[16] = malloc(TEST_COUNT * sizeof(*ip_array));
    if (ip_array == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }

	// Randomly generate an array of IP addresses    for (int i = 0; i < TEST_COUNT; i++) {
        generate_random_ip(ip_array[i]);
    }

    // Test sscanf method    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 method takes time: %.6f seconds\n", sscanf_time);
    printf("Sscanf method failed: %d\n", sscanf_fail_count);

    // Test inet_aton method    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 method takes time: %.6f seconds\n", inet_aton_time);
    printf("inet_aton method failed: %d\n", inet_aton_fail_count);

    // Compare the efficiency of the two methods    if (sscanf_time < inet_aton_time) {
        printf("sscanf method is faster and is % %.2f times more efficient\n", inet_aton_time / sscanf_time);
    } else {
        printf("inet_aton method is faster and is %.2f times more efficient\n", sscanf_time / inet_aton_time);
    }

    return 0;
}

/*
 sscanf method takes time: 0.116505 seconds
 sscanf method failed: 0
 inet_aton method takes time: 0.043936 seconds
 Inet_aton method failures: 0
 inet_aton is faster and 2.65 times more efficient
 */

The above is the detailed content of converting dotted decimal IP strings into 4 integers using C language. For more information about converting C language IP strings into 4 integers, please pay attention to my other related articles!