簡體   English   中英

在C中合並和排序結構數組

[英]Merging and Sorting struct array in c

我正在嘗試制作一個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的結構並在其中存儲值,還是只合並當前數組? 時間效率不是必需的。

如果有用的話,我可以提供樣本輸入文件。

如果我已正確理解您的要求,則要從同一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地址的所有大小添加到最初包含該地址的第一個struct元素中。 您的第二個printf()循環現在應該是:

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

至少我認為您應該先合並然后再排序,但這當然取決於您要實現的目標。

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++;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM