I am trying to make a c99 program that reports the number of bytes downloaded by devices using WiFi.
我正在尝试制作一个c99程序,报告设备使用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.
它接收一个数据包文件作为输入,并将每个数据包分类为包含mac id和数据包大小的结构数组。
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.
现在我试图按升序排序结构数组,并添加相同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);
}
}
}
}
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.
它排序很好,但合并是问题。我应该使用另一个名为output的结构并将值存储在那里,还是应该合并当前数组?时间效率是没有必要的。
I can provide the sample input file if it would be useful.
如果它有用,我可以提供示例输入文件。
2 个解决方案
#1
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++;
}
}
#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):
如果我已正确理解您,您想要从同一个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;
}
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:
现在,您已将每个mac地址的所有大小添加到最初包含该地址的第一个struct元素。你的第二个printf()循环现在应该是:
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.
至少我认为你应该首先合并然后排序,但这取决于你想要实现的目标。
#1
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++;
}
}
#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):
如果我已正确理解您,您想要从同一个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;
}
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:
现在,您已将每个mac地址的所有大小添加到最初包含该地址的第一个struct元素。你的第二个printf()循环现在应该是:
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.
至少我认为你应该首先合并然后排序,但这取决于你想要实现的目标。