【问题标题】:Reading a file of digits into a linked list将数字文件读入链表
【发布时间】:2020-03-19 22:33:02
【问题描述】:

我没有收到任何错误;该代码有效,但仅显示第一个元素,不显示其他元素。我想用链表显示文件中的所有数字。我的错误是什么?

numbers.txt中的数字:

9 2 3
4 2 3
1 2 9
2 4 8
7 5 9
2 4 7

这是我的代码:

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

struct NUMBERS{
    int katsayi;
    int taban;
    int us;
    NUMBERS *next;
};

int main(){
    NUMBERS *temp=NULL;
    NUMBERS *list=NULL; // to keep first element
    NUMBERS *head=NULL; // temp for the first element
    FILE *fp=fopen("numbers.txt","r+");
    while(!feof(fp)){
        temp=(NUMBERS*)malloc(sizeof(NUMBERS));
        fscanf(fp,"%d %d %d",&temp->katsayi,&temp->taban,&temp->us);
        temp->next=NULL;
        if(list==NULL){
            list=temp;
        }
        else{
            head=list;
            while(head->next!=NULL){
                head=head->next;
            }
            head=temp;
        }

    }
    head=list; 
    while(head!=NULL){  
        printf("%d %d %d",head->katsayi,head->taban,head->us);
        head=head->next;
    }
    return 0;
}

【问题讨论】:

  • else 部分的末尾,您使用head=temp。那么在这之前发生的所有head=... 分配的意义何在???您不妨摆脱所有这些(包括while 循环),并留下head=temp。我希望这会导致您遇到问题,因为您显然不打算只做head=temp
  • 是的,我的错:/,谢谢你的回答

标签: c file linked-list singly-linked-list


【解决方案1】:

这里有几个问题:

  • while(!feof(fp)){wrong 因为它告诉我们什么时候读到了文件的末尾,而不是什么时候读到最后一行(详见链接)。可以查看fscanf != EOF是否返回。我假设您帖子中的空白行是格式错误,但如果不是,您可以使用 fscanf 的返回值来确保所有 3 位数字都匹配并跳过它们不匹配的任何行。
  • 代码不应该编译,因为NUMBERS 还没有被typedef'd。不需要全部大写,这通常是为常量保留的。
  • No needmalloc 的结果转换为 C。
  • 插入新节点的代码:

        head=list;
        while(head->next!=NULL){
            head=head->next;
        }
        head=temp;
    

    没有多大意义。遍历列表后,head 被简单地设置为temp,撤消遍历。在任何情况下,我们都不应该为了添加单个节点而遍历整个列表。解决方案是使用tail 节点,该节点始终指向列表中的最后一个元素。

  • 代码泄漏内存。 freemalloc
  • 打开文件时检查错误并正常退出。
  • 考虑一个LinkedList 结构,它封装了头/尾指针并具有相应的插入/删除/遍历/释放功能。 main 也应该分解成函数(读者练习)。

这是最初的重写:

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

typedef struct Numbers {
    int katsayi;
    int taban;
    int us;
    struct Numbers *next;
} Numbers;

int main() {
    Numbers *temp = NULL;
    Numbers *list = NULL; 
    Numbers *tail = NULL; 
    Numbers dummy;
    char file[] = "numbers.txt";
    FILE *fp = fopen(file, "r");

    if (!fp) {
        fprintf(stderr, "%s %d: could not open %s \n", 
                __FILE__, __LINE__, file);
        exit(1);
    }

    while (fscanf(fp, "%d %d %d", 
           &dummy.katsayi, &dummy.taban, &dummy.us) != EOF) {
        temp = malloc(sizeof(*temp));
        memcpy(temp, &dummy, sizeof(*temp));
        temp->next = NULL;

        if (list) {
            tail->next = temp;
        }
        else {
            list = temp;
        }

        tail = temp;
    }

    for (temp = list; temp; temp = temp->next) {
        printf("%d %d %d\n", 
               temp->katsayi, temp->taban, temp->us);
    }

    for (temp = list; temp;) {
        Numbers *prev = temp;
        temp = temp->next;
        free(prev);
    }

    return 0;
}

输出:

9 2 3
4 2 3
1 2 9
2 4 8
7 5 9
2 4 7

【讨论】:

  • 非常感谢,现在可以使用了。你的代码教了很多东西
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多