我有一个程序,要求用户输入一些IP地址,以存储在以下结构数组中:
struct ipaddr{
int octet1;
int octet2;
int octet3;
int octet4;
}; typedef struct ipaddr ipaddr_t;
struct ipaddr addr_array[];
我需要创建一个函数来检查struct数组中的所有ip地址,并检查它们是否属于同一个子网(即ip地址的前三个xxx.xxx.xxx是相同的,例如:
123.123.123.1
123.123.123.2
123.123.123.3
然后对于每个子网,该函数在其自己的行上打印属于该子网的所有IP地址,例如:
123.123.123.1 123.123.123.2 123.123.123.3 123.123.123.4
144.144.144.1 144.144.144.2 144.144.144.3 144.144.144.4
并且打印需要保留用户输入的ip地址的顺序
到目前为止,我只能比较两个结构是否具有相同的子网,具有以下功能:
int is_same_subnet(ipaddr_t ip1, ipaddr_t ip2){
if(ip1.octet1 == ip2.octet1 &&
ip1.octet2 == ip2.octet2 &&
ip1.octet3 == ip2.octet3){
return 1;
}
else return 0;
}
但我需要为这样的结构数组执行此操作(这不起作用,但这是我的尝试):
void print_same_subnet(const ipaddr_t addr_array[], int addr_array_len){
int i, k;
for(i=0; i < addr_array_len; i++){
for(k=1; k < addr_array_len; k++){
if(addr_array[i].octet1 == addr_array[k].octet1 &&
addr_array[i].octet2 == addr_array[k].octet2 &&
addr_array[i].octet3 == addr_array[k].octet3)
{
printf("%i.%i.%i.%i %i.%i.%i.%i \n", addr_array[i].octet1, addr_array[i].octet2, addr_array[i].octet3, addr_array[i].octet4,
addr_array[k].octet1, addr_array[k].octet2, addr_array[k].octet3, addr_array[k].octet4);
}
}
}
}
对初学者的任何帮助非常感谢!
void print_same_subnet(const ipaddr_t addr_array_1[], const ipaddr_t addr_array_2[], int addr_array_len)
{
for(i=0; i < addr_array_len; i++)
{
if(is_same_subnet(addr_array_1[i], addr_array_2[i]))
{
//Do what you want here
}
}
}
如果你不介意更改数组,一种方法是对地址进行排序,使它们组合在一起,从而可以更容易地作为一组输出:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
struct ipaddr{
int octet1;
int octet2;
int octet3;
int octet4;
};
typedef struct ipaddr ipaddr_t;
int compare_ips (const ipaddr_t *ip1, const ipaddr_t *ip2) {
if (ip1->octet1 != ip2->octet1) return ip1->octet1 - ip2->octet1;
if (ip1->octet2 != ip2->octet2) return ip1->octet2 - ip2->octet2;
if (ip1->octet3 != ip2->octet3) return ip1->octet3 - ip2->octet3;
return ip1->octet4 - ip2->octet4;
}
typedef int (*qsort_comparator)(const void *, const void*);
int is_same_subnet(ipaddr_t ip1, ipaddr_t ip2){
return (ip1.octet1 == ip2.octet1 &&
ip1.octet2 == ip2.octet2 &&
ip1.octet3 == ip2.octet3);
}
void print_same_subnet(ipaddr_t addr_array[], int addr_array_len){
qsort (addr_array, addr_array_len, sizeof (ipaddr_t), (qsort_comparator) compare_ips);
bool fresh_match = true;
for (int i = 0; i < addr_array_len - 1; i++) {
if (is_same_subnet (addr_array[i], addr_array[i+1])) {
if (fresh_match) {
printf("%i.%i.%i.%i ", addr_array[i].octet1, addr_array[i].octet2, addr_array[i].octet3, addr_array[i].octet4);
fresh_match = false;
}
printf("%i.%i.%i.%i ", addr_array[i+1].octet1, addr_array[i+1].octet2, addr_array[i+1].octet3, addr_array[i+1].octet4);
} else {
if (!fresh_match) {
printf ("\n");
}
fresh_match = true;
}
}
if (!fresh_match) {
printf ("\n");
}
}
int main (void) {
struct ipaddr addr_array[] = {
{ 10, 32, 39, 49 },
{ 10, 32, 25, 95 },
{ 10, 32, 39, 27 },
{ 10, 32, 39, 88 },
{ 10, 32, 25, 22 },
{ 10, 99, 25, 22 },
};
print_same_subnet (addr_array, 6);
}
一种简单的方法是构建一个相同大小的辅助数组,以记下已经处理过的地址。代码可以(或多或少):
void print_same_subnet(const ipaddr_t addr_array[], int addr_array_len){
int i, k;
int *seen = malloc(addr_array_len * sizeof(int)); // allocate auxilliary array
for(i=0; i<addr_array_len; i++) seen[i] = 0; // and set it to 0
for(i=0; i < addr_array_len; i++){
if (seen[i]) continue; // do not process twice the same row
printf("%i.%i.%i.%i", addr_array[i].octet1, addr_array[i].octet2,
addr_array[i].octet3, addr_array[i].octet4);
for(k=i+1; k < addr_array_len; k++){ // search all addresses sharing same network
if (seen[k]) continue; // ignore already seen addresses
if (is_same_subnet(addr_array[i], addr_array[k])) {
seen[k] = 1; // note it
printf(" %i.%i.%i.%i", addr_array[k].octet1, // and display it on same line
addr_array[k].octet2, addr_array[k].octet3, addr_array[k].octet4);
}
}
printf("\n");
}
free(seen); // free the auxilliary array
}