C:将文件读取到单链表并返回头指针的函数?

C:将文件读取到单链表并返回头指针的函数?,c,C,我正在编写一个程序,它将填充一个单链表,并通过将足球队和比赛结果按顺序存储在节点结构中来处理包含足球队和比赛结果的文件中的数据。尝试遍历和显示已填充的链表时会出现问题 我试过了 1.将头指针作为参数传递 在函数内创建头节点,然后返回它 3.(如我提供的代码)两者都有 这些都不管用。创建了一些测试printf-s 结构: typedef struct node{ char host[50]; char* guest[50]; int nrgh; int nrg

我正在编写一个程序,它将填充一个单链表,并通过将足球队和比赛结果按顺序存储在节点结构中来处理包含足球队和比赛结果的文件中的数据。尝试遍历和显示已填充的链表时会出现问题

我试过了

1.将头指针作为参数传递

  • 在函数内创建头节点,然后返回它
  • 3.(如我提供的代码)两者都有

    这些都不管用。创建了一些测试printf-s

    结构:

       typedef struct node{
        char host[50];
        char* guest[50];
        int nrgh;
        int nrgg;
        struct node* next;
       }node;
    
    加载器功能:

       node* load_ll(node* head,char* file_name){
        FILE* fp;
    
        fp = fopen(file_name,"r");
        node *curr;
        curr = head;
        if(fp == NULL){
            printf("Greska pri otvaranju fajla.");
            exit(1);
        }
    
        char buff[100];
        char* tok;
    
        while(fgets(&buff,100,fp) != NULL){
    
             curr = (node*)malloc(sizeof(node));
                if(curr == NULL)
                {
                printf("Error creating a node.");
                exit(1);
                }
    
          tok = strtok(buff,",");
          strcpy(curr->host,tok);
          tok = strtok(NULL,",");
          strcpy(curr->guest,tok);
          tok = strtok(NULL,",");
          curr->nrgh = atoi(tok);
          tok = strtok(NULL,",");
          curr->nrgg = atoi(tok);
    
          curr->next = NULL;
    
          printf("%s\n",curr->host);
          printf("%s\n",curr->guest);
          printf("%d\n",curr->nrgh);
          printf("%d\n",curr->nrgg);
          curr=curr->next;
    
          return head;
    
        }
    
    void print_matches(node* head){
     node* curr = head; 
    
     while(curr->next != NULL){
    
       printf("%s\t%d\n%s\t%d\n",curr->host,curr->nrgh,curr->guest,curr->nrgg);
       curr = curr->next;
    
        }
        return;
    }
    
    遍历和显示功能:

       node* load_ll(node* head,char* file_name){
        FILE* fp;
    
        fp = fopen(file_name,"r");
        node *curr;
        curr = head;
        if(fp == NULL){
            printf("Greska pri otvaranju fajla.");
            exit(1);
        }
    
        char buff[100];
        char* tok;
    
        while(fgets(&buff,100,fp) != NULL){
    
             curr = (node*)malloc(sizeof(node));
                if(curr == NULL)
                {
                printf("Error creating a node.");
                exit(1);
                }
    
          tok = strtok(buff,",");
          strcpy(curr->host,tok);
          tok = strtok(NULL,",");
          strcpy(curr->guest,tok);
          tok = strtok(NULL,",");
          curr->nrgh = atoi(tok);
          tok = strtok(NULL,",");
          curr->nrgg = atoi(tok);
    
          curr->next = NULL;
    
          printf("%s\n",curr->host);
          printf("%s\n",curr->guest);
          printf("%d\n",curr->nrgh);
          printf("%d\n",curr->nrgg);
          curr=curr->next;
    
          return head;
    
        }
    
    void print_matches(node* head){
     node* curr = head; 
    
     while(curr->next != NULL){
    
       printf("%s\t%d\n%s\t%d\n",curr->host,curr->nrgh,curr->guest,curr->nrgg);
       curr = curr->next;
    
        }
        return;
    }
    
    主要内容:

    来自“Loader function”的Printf-s显示列表被正确填充,尽管如此,我仍然在尝试调用“print_matches”函数时遇到“Segmentation fault”。当从“加载程序函数”返回时,我怀疑与作用域有关的问题。但我不知道如何继续前进


    谢谢您的帮助。

    您可以填充一个新节点,但不要将其链接到“curr”


    您还可以保存第一个元素,以便将其作为列表的头部而不是尾部返回。您可能希望在进入循环之前将curr设置为NULL,curr在代码中未定义,访问它很可能会导致segfault

    无需将head指针传递到
    load\u ll
    ,因为它应该创建一个列表并返回指向所创建列表头部的指针。此外,当前版本的
    load\u ll
    不会将分配的列表节点链接在一起

    下面是一个版本的
    load\u ll
    ,不带
    head
    参数:

    node* load_ll(char* file_name){
        FILE* fp;
        node *head = NULL;
        node* tail = NULL;
        node* curr;
    
        fp = fopen(file_name,"r");
        if(fp == NULL){
            printf("Greska pri otvaranju fajla.");
            exit(1);
        }
    
        char buff[100];
        char* tok;
    
        while(fgets(&buff,100,fp) != NULL){
    
            curr = (node*)malloc(sizeof(node));
            if(curr == NULL)
            {
                printf("Error creating a node.");
                exit(1);
            }
    
            tok = strtok(buff,",");
            strcpy(curr->host,tok);
            tok = strtok(NULL,",");
            strcpy(curr->guest,tok);
            tok = strtok(NULL,",");
            curr->nrgh = atoi(tok);
            tok = strtok(NULL,",");
            curr->nrgg = atoi(tok);
    
            curr->next = NULL;
    
            printf("%s\n",curr->host);
            printf("%s\n",curr->guest);
            printf("%d\n",curr->nrgh);
            printf("%d\n",curr->nrgg);
    
            if(tail != NULL)
                tail->next = curr;
            else
                head = curr;
            tail = curr;
        }
    
        return head;
    }
    
    向函数添加
    head
    参数的一个可能用途是将新条目附加到现有列表中。这可以通过修改上述函数的开头来实现,如下所示:

    node* load_ll(node* head, char* file_name){
        FILE* fp;
        node* tail = head;
        node* curr;
    
        if(tail != NULL){
            // find tail of list
            while(tail->next != NULL)
                tail = tail->next;
        }
    
        /* remainder of function as before */
    
        return head;
    }
    
    要创建新列表,请将其命名为:

    head = load_ll(NULL, file_name);
    
    head = load_ll(head, file_name);
    
    要附加到现有列表,请将其称为:

    head = load_ll(NULL, file_name);
    
    head = load_ll(head, file_name);
    
    由于在附加到现有列表时,
    head
    不会更改,因此在这种情况下,可以省略对
    head
    的赋值

    您可以使用相同的调用创建新列表或附加到现有列表,如下所示:

    node* load_ll(node* head, char* file_name){
        FILE* fp;
        node* tail = head;
        node* curr;
    
        if(tail != NULL){
            // find tail of list
            while(tail->next != NULL)
                tail = tail->next;
        }
    
        /* remainder of function as before */
    
        return head;
    }
    
    创建新列表:

    head = NULL;
    head = load_ll(head, file_name);
    
    附加到现有列表:

    head = load_ll(head, file_name);
    

    load\u ll
    函数返回的是什么?另外,您实际上没有创建链接列表。。。只要创建一个独立的
    节点
    结构集即可。分配
    curr=curr->next
    不会做你显然认为它会做的事。你分配
    curr
    ,但一旦你这样做了,我就看不出你会把它放在列表中的什么地方???您不检查head是否为NULL,您分配curr,然后您只分配另一个节点,但您从不将任何内容链接在一起。当您这样使用它时,
    head
    中的值是什么:
    node*head=load\ll(head,“utakmice.txt”)?由于尝试遍历列表,仍然存在“分段错误”。我认为问题在于段权限``while(curr->next!=NULL){printf(“%s\t%d\n%s\t%d\n”,curr->host,curr->nrgh,curr->guest,curr->nrgg);curr=curr->next;}``看到我指的是什么了吗?即使在相同的函数中,这也会导致seg_f?同样,过程如下1。将列表的标题传递给函数2。分配curr=head(用于将head保存为第一个返回)3。(记住代码)创建新节点4。链接它5。当一切都完成后,返回头(第一个节点)仍然。。。分段错误。@brapej分段错误可能是因为您传递了未初始化的指针,而在此版本中它被取消引用:
    curr->next=newNode哪个可以crash@brapej开发人员应该首先学习的事情之一是如何使用调试器。e、 在这种情况下,你会看到程序崩溃的确切位置。谢谢你的回答!这解决了我的问题。我将进一步研究它,打破我头脑中的误解。:)