0

I am trying to make a c99 program that reports the number of bytes downloaded by devices using WiFi.

It takes in a packet file as input, and each packet is sorted into an array of structs that contain the mac id and size of packet.

Now I am trying to sort out the array of structs in ascending order, and add the bytes of the same mac address and delete the added record.

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

You can compile in command line using:

$: gcc main.c

run using:

$: ./a.out packets

It is sorting it fine but the merging is the issue. Should i use another struct called output and store the values in there or should i just merge up the current array? time-efficiency is not necessary.

I can provide the sample input file if it would be useful.

4
  • the mergeMac2 function is not merging all the same mac id's together Commented Sep 12, 2013 at 14:53
  • Please properly indent your code. Hint: Using tabs does not work well. Commented Sep 12, 2013 at 14:55
  • do you want me to repost it? Commented Sep 12, 2013 at 15:07
  • It seems odd that you have two structure types, struct packetStruct and struct output containing the same data fields. Wouldn't it be simpler to use just one structure type? Commented Sep 12, 2013 at 15:22

2 Answers 2

1

If I have understood you correctly you want to add all sizes from the same mac address. Then mergeMac2() should be like that (edit: now it's a version that completely preserves the original macadd array):

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

Now you have added all sizes for each mac address to the first struct element that originally contained that address. Your second printf() loop should now be:

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

At least I think you should first merge and then sort but that depends on what you want to achieve, of course.

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.