使用 strtok 从文件中获取输入

using strtok to get input from file

我正在尝试创建一个程序,该程序从一个文件中获取多个进程(名称、开始时间、剩余时间),然后使用循环算法来处理队列。

问题是,当我尝试使用 strtok()fgets() 对文件的每一行进行标记时,进程名称总是错误的。

例如,如果第一行是 P1 0 3 输出是这样的:

void RoundRobin(char *filename) {
    Queue *q = initQueue();
    char string[MAX_SIZE];
    FILE *file;
    Process process[20];
    char *token;
    file = fopen(filename, "r");
    if (!file) {
        printf("File Cannot Be Opened");
    }
    fgets(string, 150, file);
    token = strtok(string, "=");
    token = strtok(NULL, "+");
    int time_quantum = atoi(token);
    int process_count = 0;
    while (fgets(string, 150, file)) {
        char *token1;
        token1 = strtok(string, " ");
        process[process_count].name = token1;

        token1 = strtok(NULL, " ");
        process[process_count].starting_time = atoi(token1);

        token1 = strtok(NULL, " ");
        process[process_count++].remaining_time = atoi(token1);
        token1 = strtok(NULL, " ");
    }

    for (int i = 0; i < process_count; i++) {
        printf("%s  %d  %d\n", process[i].name, process[i].starting_time, process[i].remaining_time);
    }

    fclose(file);
}

您正在为所有令牌解析重复使用单个 char[]fgets() 每次都会覆盖 char[] 的内容,而 strtok() 将 return 指向 char[] 内部的内存指针。因此,每次您从文件中读取新行时,您之前存储在 process[] 数组中的指针仍指向同一内存,但该内存的内容已被更改。

您需要为每个要保存在 process[] 数组中的 name 分配一个单独的 char[] 字符串。您可以为此使用 strdup(),例如:

while (fgets(string, 150, file)){
    char* token1 token1 = strtok(string, " ");
    process[process_count].name = strdup(token1); // <-- HERE

    ...
}

// use process[] as needed...

for(int i = 0; i < process_count; i++){
    free(process[i].name);
}

问题是 strtok() returns 指向它解析的行的指针。因此,process 数组中的所有条目都指向通过调用 fgets().

修改的同一个 string 数组

您必须复制存储在流程描述结构中的字符串:

void RoundRobin(const char *filename) {
    char string[MAX_SIZE];
    Process process[20];
    Queue *q = initQueue();
    char *token;
    FILE *file;
    file = fopen(filename, "r");
    if (!file) {
        printf("Cannot open file %s\n", filename);
        return;
    }
    int time_quantum = 0;
    int process_count = 0;

    if (fgets(string, sizeof string, file)
    &&  (token = strtok(string, "=")) != NULL
    &&  (token = strtok(NULL, "+")) != NULL) {
        time_quantum = atoi(token);
    }
    while (fgets(string, sizeof string, file)) {
        char *token1;

        if ((token1 = strtok(string, " ")) == NULL)
            contine;
        process[process_count].name = strdup(token1);

        if ((token1 = strtok(string, " ")) == NULL)
            contine;
        process[process_count].starting_time = atoi(token1);

        if ((token1 = strtok(string, " ")) == NULL)
            contine;
        process[process_count].remaining_time = atoi(token1);
        process_count++;
    }

    for (int i = 0; i < process_count; i++) {
        printf("%s  %d  %d\n", process[i].name, process[i].starting_time, process[i].remaining_time);
    }
    for (int i = 0; i < process_count; i++) {
        free(process[i].name);
    }
    fclose(file);
}