代码之家  ›  专栏  ›  技术社区  ›  Ian Zurutuza

C: fgets用于构建字符的链接列表*

  •  1
  • Ian Zurutuza  · 技术社区  · 7 年前

    我正在使用 fgets() 错了吗?

    char * )将每一新行添加到LL的末尾。我从文件中读取这些行,但由于某种原因,每一行都会被正在处理的当前行覆盖,只有在使用 fgets() 内部 while 循环,但add函数似乎正确地接收了每一行。

    main() 没有问题。

    下面是一个示例输入文件:

    输入txt:

    This life, which had been the
    tomb of his virtue and of his
    honour, is but a walking
    shadow; a poor player, that
    struts and frets his hour upon
    the stage, and then is heard
    no more: it is a tale told by an
    idiot, full of sound and fury,
    signifying nothing.
        --William Shakespeare
    

    代码:

    #include <stdio.h> //printf, fopen
    #include <stdlib.h> //exit, EXIT_FAILURE
    #include <string.h> //strlen
    
    struct node {
        char *line;
        struct node *next;
    };
    
    void print(struct node *node);
    
    void add(struct node **head, char *newLine) {
        //printf("%s", newLine);
    
        struct node *new_node = (struct node *)malloc(sizeof(struct node));
        struct node *curr = *head;
    
        new_node->line = newLine;
        new_node->next = NULL;
    
        if (*head == NULL) {
            *head = new_node;
        } else {
            while (curr->next != NULL) {
                curr = curr->next;
            }
            curr->next = new_node;
        }
        print(*head);
    }
    
    void print(struct node *node) {
        printf("\n");
    
        while (node != NULL) {
            printf("%s\n", node->line);
            node = node->next;
        }
    }
    
    int main(int argc, char *argv[16]) {
        char newLine[81];
        struct node *head = NULL;
        FILE *fp = fopen(argv[1], "r");
    
        if (fp == NULL) {
            printf("ERROR: file open failed");
            exit(EXIT_FAILURE);
        }
    
        while (fgets(newLine, 81, fp)) {
            add(&head, newLine);
        }
    
        add(&head, "why");
        add(&head, "does");
        add(&head, "this");
        add(&head, "work??");
    
        fclose(fp);
    
        print(head);
    
        return 0;
    }
    

    3 回复  |  直到 7 年前
        1
  •  2
  •   Gambit Support    7 年前

    您的问题在于add()方法。 它不断向列表添加相同的缓冲区指针。 您需要将列表中的缓冲区复制到新分配的空间,即。 节点->行也需要进行malloced,并将换行复制到其中。

        2
  •  1
  •   Some programmer dude    7 年前

    你有 全部的

    最简单的解决方案是使节点结构中的字符串成为数组,并将字符串复制到其中。

    使用常量字符串文字的区别在于,每个字符串都是不同的数组。

        3
  •  1
  •   chqrlie    7 年前

    您必须为每一行分配内存。按照当前编码,所有节点都指向 main() fgets() .

    还要注意,添加到列表中的每一行都包含一个终止换行符,您可能应该在调用之前去掉它。

    #include <stdio.h>  // printf, fopen
    #include <stdlib.h> // exit, EXIT_FAILURE
    #include <string.h> // strlen, strdup
    
    struct node {
        char *line;
        struct node *next;
    };
    
    void print(struct node *node);
    
    void add(struct node **head, char *newLine) {
        //printf("%s", newLine);
    
        struct node *new_node = malloc(sizeof(struct node));
        struct node *curr = *head;
    
        new_node->line = strdup(newLine);
        new_node->next = NULL;
    
        if (*head == NULL) {
            *head = new_node;
            return;
        }
    
        while (curr->next != NULL) {
            curr = curr->next;
        }
    
        curr->next = new_node;
        print(*head);
    }
    
    void print(const struct node *node) {
        printf("\n");
    
        while (node != NULL) {
            printf("%s\n", node->line);
            node = node->next;
        }
    }
    
    int main(int argc, char *argv[16]) {
        char newLine[81];
        struct node *head = NULL;
        FILE *fp = fopen(argv[1], "r");
    
        if (fp == NULL) {
            printf("ERROR: file open failed");
            exit(EXIT_FAILURE);
        }
    
        while (fgets(newLine, sizeof newLine, fp)) {
            newLine[strcspn(newLine, "\n")] = '\0'; // strip the newline if present
            add(&head, newLine);
        }
    
        add(&head, "why");
        add(&head, "does");
        add(&head, "this");
        add(&head, "work??");
    
        fclose(fp);
    
        print(head);
    
        return 0;
    }