c - 将数据存储在两个彼此相关的数组中

标签 c

标题很难创建,但我会尽力解释。

因此,我尝试创建一个程序来读取跟踪文件并使用不同的时间量子来获得完成所有进程的最佳时间。

我需要做的是将进程存储在数据结构中,并将每个进程的事件存储在数据结构中。

跟踪文件示例:

process 1 200 {
i/o 100 usb2 1600
i/o 110 hd 1000
exit 400
}

process 2 250 {
i/o 100 hd 1000
exit 500
}


这只是跟踪文件的一个示例。我尝试过的是将进程号存储在数组中,将事件存储在数组中。

#define CHAR_COMMENT            '#'
#define MAXWORD                 20

void parse_tracefile(char program[], char tracefile[])
{
//  ATTEMPT TO OPEN OUR TRACEFILE, REPORTING AN ERROR IF WE CAN'T
    FILE *fp    = fopen(tracefile, "r");

    if(fp == NULL) {
        printf("%s: unable to open '%s'\n", program, tracefile);
        exit(EXIT_FAILURE);
    }

    char line[BUFSIZ];
    int  lc     = 0;
//  READ EACH LINE FROM THE TRACEFILE, UNTIL WE REACH THE END-OF-FILE

    char devices[MAX_DEVICES]; // Store the device names
    char device_size[MAX_DEVICES]; // Store the size of each device
    char processes[MAX_PROCESSES]; // Store the processes
    int process_time[MAX_PROCESSES]; // Store the time of each process
    int data_transfer[MAX_EVENTS_PER_PROCESS]; // Store the data transfer amount
    char event[MAX_PROCESSES][MAX_EVENTS_PER_PROCESS];

    while(fgets(line, sizeof line, fp) != NULL) {
        ++lc;

//  COMMENT LINES ARE SIMPLY SKIPPED
        if(line[0] == CHAR_COMMENT) {
            continue;
        }

//  ATTEMPT TO BREAK EACH LINE INTO A NUMBER OF WORDS, USING sscanf()
        char    word0[MAXWORD], word1[MAXWORD], word2[MAXWORD], word3[MAXWORD];
        int nwords = sscanf(line, "%s %s %s %s", word0, word1, word2, word3);

//      printf("%i = %s", nwords, line);

//  WE WILL SIMPLY IGNORE ANY LINE WITHOUT ANY WORDS
        if(nwords <= 0) {
            continue;
        }

//  LOOK FOR LINES DEFINING DEVICES, PROCESSES, AND PROCESS EVENTS
        if(nwords == 4 && strcmp(word0, "device") == 0) {
            // DEVICE FOUND STORE THIS SOMEWHERE
        }

        else if(nwords == 1 && strcmp(word0, "reboot") == 0) {
            system_time = 0;
        }

        else if(nwords == 4 && strcmp(word0, "process") == 0) {
            processes[x] = word1;
            process_time[x] = atoi(word2);
        }

        else if(nwords == 4 && strcmp(word0, "i/o") == 0) {
            //  AN I/O EVENT FOR THE CURRENT PROCESS, STORE THIS SOMEWHERE

        }

        else if(nwords == 2 && strcmp(word0, "exit") == 0) {

            //  PRESUMABLY THE LAST EVENT WE'LL SEE FOR THE CURRENT PROCESS
        }

        else if(nwords == 1 && strcmp(word0, "}") == 0) {
            continue;   //  JUST THE END OF THE CURRENT PROCESS'S EVENTS
        }
        else {
            printf("%s: line %i of '%s' is unrecognized",
                        program, lc, tracefile);
            exit(EXIT_FAILURE);
        }
    }
    fclose(fp);
}

#undef  MAXWORD
#undef  CHAR_COMMENT

我需要做的是,如果我得到进程[0](即进程1),我想要事件[]数组中进程1下的所有事件。这可能吗?可能有数百个进程。

最佳答案

这是对您的代码的快速而肮脏的改编,只是为了给您一个想法。

进程和事件被逐一重新分配,效率很低(C++ 中的 std::vector 策略会更好)。

我不知道存储信息的用途,所以我只是在这里存储字符串(您应该适应您的实际需要)。

主要思想是,如果您知道一个进程,您将获得另一个数组中其事件的索引范围。
如果你知道一个事件,你将获得它的进程在另一个数组中的索引。


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

#define CHAR_COMMENT '#'
#define MAXWORD      20

typedef struct
{
  int id;
  int info;
  int event_begin;
  int event_end;
} ProcessInfo;

typedef struct
{
  int process_index; /* optional, for back link */
  char info1[MAXWORD];
  char info2[MAXWORD];
  char info3[MAXWORD];
  char info4[MAXWORD];
} EventInfo;

void
parse_tracefile(const char *program,
                const char *tracefile,
                ProcessInfo **inout_processes,
                int *inout_process_count,
                EventInfo **inout_events,
                int *inout_event_count)
{
  ProcessInfo *processes=*inout_processes;
  int process_count=*inout_process_count;
  EventInfo *events=*inout_events;
  int event_count=*inout_event_count;

  FILE *fp    = fopen(tracefile, "r");

    if(fp == NULL) {
        printf("%s: unable to open '%s'\n", program, tracefile);
        exit(EXIT_FAILURE);
    }

    char line[BUFSIZ];
    int  lc     = 0;
//  READ EACH LINE FROM THE TRACEFILE, UNTIL WE REACH THE END-OF-FILE

    // char devices[MAX_DEVICES]; // Store the device names
    // char device_size[MAX_DEVICES]; // Store the size of each device
    // char processes[MAX_PROCESSES]; // Store the processes
    // int process_time[MAX_PROCESSES]; // Store the time of each process
    // int data_transfer[MAX_EVENTS_PER_PROCESS]; // Store the data transfer amount
    // char event[MAX_PROCESSES][MAX_EVENTS_PER_PROCESS];

    while(fgets(line, sizeof line, fp) != NULL) {
        ++lc;

//  COMMENT LINES ARE SIMPLY SKIPPED
        if(line[0] == CHAR_COMMENT) {
            continue;
        }

//  ATTEMPT TO BREAK EACH LINE INTO A NUMBER OF WORDS, USING sscanf()
        char    word0[MAXWORD], word1[MAXWORD], word2[MAXWORD], word3[MAXWORD];
        int nwords = sscanf(line, "%s %s %s %s", word0, word1, word2, word3);

//      printf("%i = %s", nwords, line);

//  WE WILL SIMPLY IGNORE ANY LINE WITHOUT ANY WORDS
        if(nwords <= 0) {
            continue;
        }

//  LOOK FOR LINES DEFINING DEVICES, PROCESSES, AND PROCESS EVENTS
        if(nwords == 4 && strcmp(word0, "device") == 0) {
            // DEVICE FOUND STORE THIS SOMEWHERE
        }

        else if(nwords == 1 && strcmp(word0, "reboot") == 0) {
            // system_time = 0;
        }

        else if(nwords == 4 && strcmp(word0, "process") == 0) {
            // processes[x] = word1;
            // process_time[x] = atoi(word2);
            ++process_count;
            processes=(ProcessInfo *)realloc(processes,
                                             sizeof(ProcessInfo)*(size_t)process_count);
            processes[process_count-1].id=atoi(word1);
            processes[process_count-1].info=atoi(word2);
            processes[process_count-1].event_begin=event_count;;
            processes[process_count-1].event_end=event_count;;
        }

        else if(nwords == 4 && strcmp(word0, "i/o") == 0) {
            //  AN I/O EVENT FOR THE CURRENT PROCESS, STORE THIS SOMEWHERE
            ++event_count;
            events=(EventInfo *)realloc(events,
                                        sizeof(EventInfo)*(size_t)event_count);
            events[event_count-1].process_index=process_count-1;
            strcpy(events[event_count-1].info1, word0);
            strcpy(events[event_count-1].info2, word1);
            strcpy(events[event_count-1].info3, word2);
            strcpy(events[event_count-1].info4, word3);
            ++processes[process_count-1].event_end;
        }

        else if(nwords == 2 && strcmp(word0, "exit") == 0) {

            //  PRESUMABLY THE LAST EVENT WE'LL SEE FOR THE CURRENT PROCESS
            ++event_count;
            events=(EventInfo *)realloc(events,
                                        sizeof(EventInfo)*(size_t)event_count);
            events[event_count-1].process_index=process_count-1;
            strcpy(events[event_count-1].info1, word0);
            strcpy(events[event_count-1].info2, word1);
            strcpy(events[event_count-1].info3, "");
            strcpy(events[event_count-1].info4, "");
            ++processes[process_count-1].event_end;
        }

        else if(nwords == 1 && strcmp(word0, "}") == 0) {
            continue;   //  JUST THE END OF THE CURRENT PROCESS'S EVENTS
        }
        else {
            printf("%s: line %i of '%s' is unrecognized",
                        program, lc, tracefile);
            exit(EXIT_FAILURE);
        }
    }
    fclose(fp);

  *inout_processes=processes;
  *inout_process_count=process_count;
  *inout_events=events;
  *inout_event_count=event_count;
}

int
main(int argc,
     char **argv)
{
  if(argc!=2)
  {
    fprintf(stderr, "usage: %s file_name\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  ProcessInfo *processes=NULL;
  int process_count=0;
  EventInfo *events=NULL;
  int event_count=0;
  parse_tracefile(argv[0], argv[1],
                  &processes, &process_count,
                  &events, &event_count);

  for(int p=0; p<process_count; ++p)
  {
    const ProcessInfo *process=processes+p;
    printf("process: %d %d\n", process->id, process->info);
    for(int e=process->event_begin; e<process->event_end; ++e)
    {
      const EventInfo *event=events+e;
      printf("  %s %s %s %s\n",
             event->info1, event->info2, event->info3, event->info4);
      if(event->process_index!=p)
      {
        fprintf(stderr, "!!!inconsistant process index!!!\n");
      }
    }
  }
  free(processes);
  free(events);
  return 0;
}

关于c - 将数据存储在两个彼此相关的数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57744170/

相关文章:

c - 传递一个包含 NULL 的结构指针突然包含一个结构而不是 NULL

c - 为什么 strchr 需要一个 int 来查找 char?

c++ - 圆的面积 使用笛卡尔平面上的点

c# - 生成随机位序列

c - 将多维数组传递给函数并编辑值

大周期的 C 函数速度优化

c - 将多个二维数组复制到一个一维数组的最快方法(C 语言)

简单 shell 的命令重新执行

c - 在linux中,为什么一个正常的进程仍然可以运行,而实时进程却不退出?

c - Linux system() 和信号处理程序导致竞争条件?