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!