我将head设置为某物,但它始终为null

时间:2018-11-17 08:15:30

标签: c pointers if-statement struct

我只是想打印出我的双向链接列表。但是,即使我清楚地将头和尾设置为某种东西,但在main中打印时它始终为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 :(得分:1)

除了在初始化部分(其中分配NULL)之外,您从未为A_head分配任何内容。因此,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;