[英]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.