将数字文件读入链表

Reading a file of digits into a linked list

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

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;
}

这里有几个问题:

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

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

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

  • 代码泄漏内存。 freemalloc.
  • 打开文件时检查错误并正常退出。
  • 考虑一个 LinkedList 结构,它封装了 head/tail 指针并具有相应的 insertion/removal/traversal/free 函数。 main 也应该分解为函数(reader 的练习)。

这是一个初始重写:

#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