C语言 在各条线路上打印IP地址的相同子网

4zcjmb1e  于 2023-03-29  发布在  其他
关注(0)|答案(3)|浏览(142)

我有一个程序,它要求用户输入一些IP地址,这些地址将存储在下面的结构体数组中:

struct ipaddr{
    int octet1;
    int octet2;
    int octet3;
    int octet4;
  }; typedef struct ipaddr ipaddr_t;

struct ipaddr addr_array[];

我需要创建一个函数来检查结构体数组中的所有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);
      } 
    }
  }
}

对于初学者的任何帮助都非常感谢!

gz5pxeao

gz5pxeao1#

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
        } 
    }
}
jdgnovmf

jdgnovmf2#

如果您不介意数组被更改,一种方法是对地址进行排序,以便将它们分组在一起,从而可以更容易地作为一个组输出:

#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);
}
r1zk6ea1

r1zk6ea13#

一个简单的方法是构建一个相同大小的辅助数组来记录已经处理了哪些地址。代码可以是(或多或少):

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
}

相关问题