Saya mencoba membuat program yang mengambil sejumlah proses (nama, waktu mulai, waktu yang tersisa) dari sebuah file, kemudian menggunakan algoritma round robin untuk menangani antrian.

Masalahnya adalah, ketika saya mencoba untuk menandai setiap baris file dengan menggunakan strtok() dan fgets(), nama prosesnya selalu salah.

Misalnya, jika baris pertama adalah P1 0 3 outputnya seperti ini:

image

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);
}
1
HosnyyHanyy 12 Mei 2021, 21:30

2 jawaban

Jawaban Terbaik

Anda menggunakan kembali satu char[] untuk semua penguraian token Anda. fgets() akan menimpa konten char[] itu setiap kali, dan strtok() akan mengembalikan pointer ke memori di dalam char[] itu. Jadi, setiap kali Anda membaca baris baru dari file, pointer sebelumnya yang sudah Anda simpan di larik process[] masih menunjuk ke memori yang sama, tetapi isi memori itu telah diubah.

Anda perlu mengalokasikan string char[] terpisah untuk setiap name yang ingin Anda simpan dalam larik process[]. Anda dapat menggunakan strdup() untuk itu, misalnya:

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);
}
1
Remy Lebeau 12 Mei 2021, 18:39

Masalahnya adalah strtok() mengembalikan pointer ke baris yang diurai. Karenanya semua entri dalam larik process menunjuk ke larik string yang sama yang dimodifikasi oleh panggilan ke fgets().

Anda harus menduplikasi string yang Anda simpan dalam struktur deskripsi proses:

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);
}
0
chqrlie 12 Mei 2021, 19:06