2016-11-21 80 views
0

我尝试从文件中设计链接列表,但在设置链接列表的第一个节点时存在一些问题。链表的数据结构被示出为下面附加的图片: Data structure of linled list读取文件时发生链接列表问题c

在我的代码,我将两个类型的结构,一个用于名称,另一个用于评分,如下:

typedef struct nodeScore{ 

    int score; 
    struct nodeScore* nextScore; 

}nodeScore; 

typedef struct nodeName{ 

    char* firstName; 
    char* lastName; 

    nodeScore* nextScore; 
    struct nodeName* nextName; 

}nodeName; 

还有一个功能可以逐行读取文件中的分数(每行包含'First name','Last name'和最多4'分数'),并返回链表头部:

nodeName* storeFile(const char* fileName, nodeName* nodeN){ 

FILE *pFile = fopen(fileName, "r"); 

char input[512]; 

char* firstName; 
char* lastName; 
int score; 

int line=0; 

nodeName* prevName; 
nodeScore* prevScore; 

while(fgets(input, 512, pFile)){ 

    printf("Line %d now.\n", ++line); 

    nodeName* ptrN = (nodeName*)malloc(sizeof(nodeName));//allocate for new node name. 

    firstName = strtok(input, " ");//first space for first name. 
    ptrN->firstName = firstName; 

    lastName = strtok(NULL, " ");//second space for last name. 
    ptrN->lastName = lastName; 

    if(line == 1){ 
     prevName = ptrN; 
     nodeN = ptrN;//allocate nodeN the return value to the first line, first node of the linked list. 

    }else{ 
     prevName->nextName = ptrN; 
     prevName = ptrN; 

    } 


    ptrN->nextName = NULL; 
    ptrN->nextScore = NULL; 

    while(score = atoi(strtok(NULL, " \n"))){//store multiple scores until  next char is space or next new line. 

     if(ptrN->nextScore == NULL){//if no link to another score. 
      nodeScore* ptrS = (nodeScore*)malloc(sizeof(nodeScore));//allocate for new score node. 

      ptrN->nextScore = ptrS; 
      ptrS->score = score; 
      ptrS->nextScore = NULL; 
      prevScore = ptrS;//record latest 'tail' of linked list. 


     }else{ 
      nodeScore* ptrS = (nodeScore*)malloc(sizeof(nodeScore)); 

      prevScore->nextScore = ptrS; 
      ptrS->score = score; 
      ptrS->nextScore = NULL; 
      prevScore = ptrS;//record latest 'tail' or linked list. 

     } 


    }//done the loop for storing multi-scores. 

}//done the loop for reading lines from file. 

return nodeN; 
} 

最后主要功能:

int main(){ 
    char file1[]={"HW5_26.txt"}; 
    nodeName* n1; 

printf("\nStart reading file '%s' and store it into linked-list.\n\n", file1); 

n1 = storeFile(file1, n1); 

printf("%s", n1->firstName);//try to see who's the first person(1st node, should be Albert Einstein), here is when I'm confused. 

return 0; 
} 

在我返回值的末尾,我送花儿给人得到“莎拉”的最后一个节点的结果,但是,我已经设置了“如果过滤器”只能从第一线做出的返回值的数据,我不知道哪个部分出了问题,如果有人能给我一些建议或想法,我会很感激,谢谢。

TXT文件是这样的:

Albert Einstein 52 67 63 
Steve Abrew 90 86 90 93 
David Nagasake 100 85 93 89 
Mike Black 81 87 81 85 
Andrew Dijkstra 90 82 95 87 
Joanne Nguyen 84 80 95 91 
Chris Walljasper 86 100 96 89 
Fred Albert 70 68 
Dennis Dudley 74 79 77 81 
Leo Rice 95 
Fred Flinstone 73 81 78 74 
Frances Dupre 82 76 79 
Dave Light 89 76 91 83 
Hua Tran 91 81 87 94 
Sarah Trapp 83 98 94 93 

我的头:

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

[请参阅此讨论,为什么不在'C'中投射'malloc()'和家族的返回值。](http://stackoverflow.com/q/605845/2173917)。 –

回答

3

的问题是您如何使用strtok,并返回指针:

firstName = strtok(input, " ");//first space for first name. 
ptrN->firstName = firstName; 

指针firstName将是一个指向数组input的指针。数组input与整个循环相同,这意味着所有名称的所有指针都将指向相同的数组。它的也是意味着只要storeFile函数返回,那些指针就会失效,因为该数组将不再存在,并且使用这些指针将导致未定义的行为

有两种可能的解决方案:一种是使用例如strdup复制字符串。另一种是在名称结构中有数组,并复制字符串。

请注意,strdup不是一个标准的C函数,但几乎所有的系统都有它。另外请注意,它会动态分配内存malloc,所以你需要在free之前的free这个节点。

+0

非常感谢你,它的工作原理。我学到了很多,再次感谢。祝你今天愉快! –