丢失链表中的根节点?

时间:2016-02-19 02:39:22

标签: c linked-list

出于某种原因,我似乎丢失了此链表中的根节点,这意味着在第一个printf语句中,ptr-> word和root->字是镜像的。我忽略了fscanf()函数可能有问题吗?有谁知道为什么会发生这种情况?

    struct word_t {
        char *word;
        int count;
        int id;
        struct word_t *next;
};
int main(int argc, char *argv[]){
        FILE *input, *output;
        int i = 0, y;
        struct word_t *ptr = NULL;
        struct word_t *root = NULL;
        root = (struct word_t*) malloc(sizeof (struct word_t));
        char word[MAXSIZE];
        input = fopen(argv[1]+6, "r");
        if (input == 0){
                printf("Error, could not open file\n.");
        }
        else{
                while(fscanf(input, "%s", word) != EOF){
                        word[MAXSIZE] = putLower(word);
                        if (i == 0){
                                root->next = NULL;
                                root->word = word;
                                root->id = i;
                                ptr = root;
                        }
                        else{
                                if (ptr != NULL){
                                        while (ptr->next != NULL){
                                                ptr = ptr->next;
                                        }
                                }

                                ptr->next = (struct word_t*) malloc(sizeof (struct word_t));
                                ptr = ptr->next;
                                ptr->next = NULL;
                                ptr->word = word;
                                ptr->id = i;
                        }
                  }
                    i++;
                    printf("ptr: %s, root: %s\n", ptr->word, root->word);
                    if (i > 400){
                            exit(1);
                    }
            }

            ptr = root;
            if (ptr != NULL){
                    while (ptr->next != NULL){
                            printf("%s\n", ptr->word);
                            ptr = ptr->next;
                    }
                    printf("%s\n", ptr->word);
            }
    }

2 个答案:

答案 0 :(得分:0)

正如Kaylum评论的那样:(见下面的三个变化)

    struct word_t {
        char word[MAXSIZE];  ///// changed
        int count;
        int id;
        struct word_t *next;
};
int main(int argc, char *argv[]){
        FILE *input, *output;
        int i = 0, y;
        struct word_t *ptr = NULL;
        struct word_t *root = NULL;
        root = (struct word_t*) malloc(sizeof (struct word_t));
        char word[MAXSIZE];
        input = fopen(argv[1]+6, "r");
        if (input == 0){
                printf("Error, could not open file\n.");
        }
        else{
                while(fscanf(input, "%s", word) != EOF){
                        word[MAXSIZE] = putLower(word);   // what does this do?
                        if (i == 0){
                                root->next = NULL;
                                strcpy(root->word, word);  ///// changed
                                root->id = i;
                                ptr = root;
                        }
                        else{
                                if (ptr != NULL){
                                        while (ptr->next != NULL){
                                                ptr = ptr->next;
                                        }
                                }

                                ptr->next = (struct word_t*) malloc(sizeof (struct word_t));
                                ptr = ptr->next;
                                ptr->next = NULL;
                                strcpy(ptr->word, word);  ///// changed
                                ptr->id = i;
                        }
                  }
                    i++;
                    printf("ptr: %s, root: %s\n", ptr->word, root->word);
                    if (i > 400){
                            exit(1);
                    }
            }

    // also, as the two printf lines in your code here were the same, your code can be replaced to the neater:
            ptr = root;

            while (ptr){
                    printf("%s\n", ptr->word);
                    ptr = ptr->next;
            }


    }

答案 1 :(得分:0)

除了不为每个单词创建缓冲区外,您的打印循环在错误的位置检查NULL并且您没有设置计数;

这是另一种方法,它以更标准的方式处理指针/根,并演示正确的内存处理。

struct node_t {
    int id;
    char *word;
    struct node_t *next;
};
int main(int argc, char *argv[]){
    FILE *input, *output;
    int i = 0, y;

    struct node_t *root = NULL; // pointer to a node, root is not a node in itself.

    struct node_t *ptr = NULL; // working pointer a current node

    // root is just a pointer, not an actual node.
    root = NULL; // no nodes yet.

    char word[MAXSIZE];

    // why +6?
    input = fopen(argv[1]+6, "r");

    if (input == 0){
            printf("Error, could not open file\n.");
    }
    else{
            // this is unsafe since scanf could
            // overflow the word buffer MAXSIZE.
            while(fscanf(input, "%s", word) != EOF)
            {
                 // what is putLower?
                 //putLower(word);
                 word[MAXSIZE-1] = 0; // correctly null terminate input.

                 // create new node
                 struct node_t *newNode = (struct node_t*) malloc(sizeof(struct node_t));
                 newNode->word = strdup(word); // copy input word into new buffer.
                 newNode->id = i; 
                 newNode->next = NULL; 

                // store first, or next node in list
                if (root == NULL)
                {
                    // first node
                    root = newNode;
                    ptr = root;
                }
                else
                {
                    // additional nodes
                    ptr->next = newNode;
                    ptr = newNode;
                }
                i++;
                printf("ptr: %s, root: %s\n", ptr->word, root->word);
                if (i > 400){
                        exit(1);
                }
            }
        }

        // loop, print, and free nodes
        ptr = root;
        while(ptr != NULL)
        {
            printf("%s\n", ptr->word);
            // free word buffer created by strdup
            free(ptr->word)
            struct node_t *tmp = ptr;
            ptr = ptr->next;
            free(tmp);
        }
    }
}