【问题标题】:Merging and Sorting struct array in c在c中合并和排序结构数组
【发布时间】:2013-09-12 14:50:56
【问题描述】:

我正在尝试制作一个 c99 程序来报告使用 WiFi 的设备下载的字节数。

它以一个数据包文件作为输入,每个数据包被排序成一个结构数组,其中包含数据包的mac id和大小。

现在我正在尝试按升序对结构数组进行排序,并添加相同mac地址的字节并删除添加的记录。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define PACKETS "sample-packets"
#define MAXMACADD 500

struct packetStruct {
    char mac[17];
    int size;
} packetStruct[MAXMACADD];

struct output {
    char mac[17];
    int size;
} output[MAXMACADD];

void sortSize(struct packetStruct* macadd, int n) {
  int j, i;

  for (i = 1; i < n; i++) {
    for (j = 0; j < n - i; j++) {
      if (macadd[j].size < macadd[j + 1].size) {
        struct packetStruct temp = macadd[j];
        macadd[j] = macadd[j + 1];
        macadd[j + 1] = temp;
      }
    }
  }
}

void mergeMac2(struct packetStruct* macadd, struct output* output, int n) {
  int i, j, k=0;

  for (i = 0; i < n; i++) {
    if (strcmp(macadd[i].mac, "\0") != 0) {
      for (j = 0; j < n; j++) {
        if (strcmp(macadd[j].mac, "\0") != 0) {
          if (strcmp(macadd[i].mac, macadd[j].mac) == 0){
            strcpy(output[k].mac, macadd[i].mac);
            output[k].size += macadd[i].size;
            macadd[i].size = 0;
          }
        } else j++;
      }            
    } else i++;
    k++;
  }
}

int readpacket() {
  char *token;
  char buf[60];
  int size;
  FILE *packet = fopen(PACKETS, "r"); //open packet file in read mode

  int i = 0;
  int j = 0; //loop control variables
  int k = 0;

  while (fgets(buf, sizeof (buf), packet) != '\0') {
    token = strtok(buf, "\t"); //tokenize buf and point to time
    token = strtok(NULL, "\t"); //point to sender mac add

    token = strtok(NULL, "\t"); //point to dest mac add
    strcpy(packetStruct[i].mac, token);

    token = strtok(NULL, "\t"); //point to byte size
    packetStruct[i].size += atoi(token);

    //printf("%i. %s\t%d\n", i, packetStruct[i].mac, packetStruct[i].size);
    i++;
  }
  fclose(packet); //close packet file

  sortSize(packetStruct, i);
  mergeMac2(packetStruct, output, i);

  for (i = 0; i < 20; i++) {
    printf("%i. %s\t%d\n", i, packetStruct[i].mac, packetStruct[i].size);
  }

  for (i=0; i < 20; i++){
    printf("%i. %s\t%d\n", i+1, output[i].mac, output[i].size);
  }
  return 0;
}

void main(int argc, char *argv[]) {
  if (argc != 2) {
    printf("%s: program needs 1 argument, but there was %d\n", argv[0], argc - 1);
    exit(EXIT_FAILURE);
  } else {
    if (strcmp(argv[1], "packets") != 0) {
      printf("%s: program expected command 'packets', but you wrote %s\n", argv[0], argv[1]);
    } else {
      if (readpacket() != 0) {
        exit(EXIT_FAILURE);
      }
    }
  }
}

您可以使用以下命令在命令行中编译:

$: gcc main.c

运行使用:

$: ./a.out packets

它的排序很好,但合并是个问题。我应该使用另一个名为 output 的结构并将值存储在其中还是应该合并当前数组?时间效率不是必需的。

如果有用的话,我可以提供示例输入文件。

【问题讨论】:

  • mergeMac2 函数没有将所有相同的 mac id 合并在一起
  • 请正确缩进您的代码。提示:使用标签效果不佳。
  • 要我转发吗?
  • 您有两种结构类型,struct packetStruct 和 struct output 包含相同的数据字段,这似乎很奇怪。只使用一种结构类型不是更简单吗?

标签: c arrays linux sorting struct


【解决方案1】:

如果我对您的理解正确,您想从同一个 mac 地址添加所有尺寸。那么mergeMac2()应该是这样的(编辑:现在是完全保留原macadd数组的版本):

  // return number of elements in output
  int mergeMac2(struct packetStruct* macadd, struct output* output, int n) {

      int i, j, k=0;

      for (i = 0; i < n; i++) {
          // '"\0" makes no difference to "" here
          //if (strcmp(macadd[i].mac, "\0") != 0) {
          if (strcmp(macadd[i].mac, "") != 0) {
              // search in putput;
              for( j=0; j<k && strcmp( macadd[i].mac, output[j].mac ) != 0; j++ ) ;
              if( j == k ) {
                  // not yet created in output     
                  strcpy( output[k].mac, macadd[i].mac );
                  output[k].size = macadd[i].size;
                  k++;
              } else {
                  output[j].size += macadd[i].size;
              }
          }

      }
      return k;
  }

现在您已将每个 mac 地址的所有大小添加到最初包含该地址的第一个结构元素中。您的第二个 printf() 循环现在应该是:

int j, n;
...
n = mergeMac2( packetStruct, output, i );
for( j=0; j<n; j++ ) {
    ...
} 

至少我认为您应该先合并然后排序,但这当然取决于您想要实现的目标。

【讨论】:

    【解决方案2】:
    void mergeMac2(struct packetStruct* macadd, struct output* output, int n)
    {
        int i, j, k = 0;
    
        for (i = 0; i < n; i++) {
            /*
             * If size is 0, the packet has already been processed.
             */
            if (macadd[i].size == 0)
               continue;
    
            memcpy(&output[k], &macadd[i], sizeof(struct packetStruct));
    
            for (j = i+1; j < n; j++) {
                /*
                 * If size is 0, the packet has already been processed.
                 */
                if (macadd[j].size == 0)
                   continue;
    
                if (strcmp(macadd[i].mac, macadd[j].mac) == 0) {
                    output[k].size += macadd[j].size;
    
                    /*
                     * Set size to 0 so that these packets won't be
                     * processed in the next pass.
                     */
                    macadd[j].size = 0;
                }
            }
            k++;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-06
      • 2015-05-16
      • 1970-01-01
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多