Я устанавливаю голову, чтобы быть чем-то, но это всегда ноль - PullRequest
0 голосов
/ 17 ноября 2018

Я просто пытаюсь распечатать свой дважды связанный список.Тем не менее, хотя я чётко настраиваю голову и хвост на что-то, всегда печатается NULL, когда я печатаю его в основном.Я не уверен, в чем проблема.Я пытался максимально упростить код.

В функции grade_word_gen вы можете ясно видеть, что я что-то устанавливаю головой, и что-то устанавливаю.

test.txt

*A*
Great
Fantastic
Lovely
*B*
Bad
Not Good
Terrible

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

struct grade {
    struct grade_word *A_head;
    struct grade_word *A_tail;

    struct grade_word *B_head;
    struct grade_word *B_tail;

};

struct grade_word {
    char *word;
    struct grade_word *next;
    struct grade_word *prev;
};

struct grade *create_grade() {

    struct grade *new_grade = malloc(sizeof(struct grade));

    // Check grade was allocated correctly
    if (new_grade == NULL) {
        fprintf(stderr, "ERROR: Could not allocate memory for grade\n");
        exit(1);
    }

    // Initialise all variables
    new_grade->A_head = NULL;
    new_grade->A_tail = NULL;

    new_grade->B_head = NULL;
    new_grade->B_tail = NULL;

    return new_grade;
}

struct grade_word *create_grade_word(char *word) {

    struct grade_word *new = malloc(sizeof(struct grade_word));

    if (new == NULL) {
        fprintf(stderr, "ERROR: Unable to allocate memory for grade_words\n");
        exit(1);
    }

    // Initialise vairables
    int len = strlen(word);
    new->word = malloc(sizeof(char) * (len + 1));
    strcpy(new->word, word);
    new->next = NULL;
    new->prev = NULL;

    return new;
}

void grade_word_gen(struct grade *grade_data) {

    FILE *fp = fopen("test.txt", "r");
    char grade;
    char buf[100 + 1];

    struct grade_word *new_node;
    struct grade_word *head;
    struct grade_word *tail;

    while (fgets(buf, 100, fp) != NULL) {

        if (buf[0] == '*' && buf[2] == '*') {
            grade = buf[1];

        } else {

            new_node = create_grade_word(buf);

            // Set next, prev, head, tail pointers
            if (grade == 'A') {
                head = grade_data->A_head;
                tail = grade_data->A_tail;
            } else {
                head = grade_data->B_head;
                tail = grade_data->B_tail;
            }

            // If first item set the head
            if (head == NULL) {
                head = new_node;
                //printf("head: %s\n", head->word);
            // Otherwise just add on to the list
            } else {
                new_node->prev = tail;
                tail->next = new_node;
            }

            tail = new_node;
        }
        // Reset buffer
        strcpy(buf, "\0");
    }

}

void print_grade_list(struct grade_word *list, char grade) {

    if (list == NULL) {
        printf("Grade %c is empty, so not grade words can be printed\n", grade);
        return;
    }

    printf("Grade: %c\n", grade);
    while (list != NULL) {
        printf("%s\n", list->word);
        list = list->next;
    }
}

int main(void) {

    struct grade *new_grade = create_grade();

    grade_word_gen(new_grade);

    print_grade_list(new_grade->A_head, 'A');
    print_grade_list(new_grade->B_head, 'B');
}

Мой вывод всегда Grade %c is empty, so not grade words can be printed.Я не понимаю, почему моя голова всегда нулевая, хотя я ее и устанавливаю.

1 Ответ

0 голосов
/ 17 ноября 2018

Вы никогда не назначаете ничего для A_head, кроме как в части инициализации, где вы назначаете NULL. Следовательно, A_head останется равным NULL:

Проблема здесь:

        if (grade == 'A') {
            head = grade_data->A_head;  // Here you make head equal A_head
            tail = grade_data->A_tail;
        } else {
            head = grade_data->B_head;
            tail = grade_data->B_tail;
        }

        // If first item set the head
        if (head == NULL) {
            head = new_node;     // Here you try to save new_node.
                                 // But you save it into head and that will not
                                 // change A_head

Вы должны иметь такой код:

grade_data->A_head = new_node;

так что вы на самом деле измените A_head.

Альтернативный способ разделения кода между вариантами A и B - двойные указатели. Как:

// Make a double pointer
struct grade_word **head;
. . .

// Make it point to either the A or B head pointer
head = &grade_data->A_head; // or head = &grade_data->B_head;
. . .

// Change A or B head pointer using head
*head = new_node;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...