在各行上打印相同的IP地址子网

问题描述 投票:0回答:3

我有一个程序,要求用户输入一些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);
      } 
    }
  }
}

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

c arrays struct ansi
3个回答
0
投票
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
        } 
    }
}

0
投票

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

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

0
投票

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

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
}
© www.soinside.com 2019 - 2024. All rights reserved.