从文件加载到链接列表

时间:2015-03-25 06:27:58

标签: c data-structures

我正在尝试将未知数量的数据从文件加载到链接列表

加载功能

void load(FILE *file, Node **head) // while feof somewhere
{
    char tempArtist[30]={'\0'}, tempAlbum[30]={'\0'}, tempTitle[30]={'\0'}, tempGenre[30]={'\0'},tempSpace='\0';
    char tempPlay[100]={'\0'}, tempRating[6]={'\0'}, tempMins[8]={'\0'}, tempSecs[8]={'\0'};

    Data *temp;

    temp=(Data*)malloc(sizeof(Data));

            while(!feof(file))
            {
            fscanf(file,"%s",tempArtist);
            fscanf(file,"%s",tempAlbum);
            fscanf(file,"%s",tempTitle);
            fscanf(file,"%s",tempGenre);
            fscanf(file,"%s",tempMins);
            fscanf(file,"%s",tempSecs);
            fscanf(file,"%s",tempPlay);
            fscanf(file,"%s",tempRating);

            temp->mins=strdup(tempMins);
            temp->secs=strdup(tempSecs);
            temp->album=strdup(tempAlbum);
            temp->artist=strdup(tempArtist);
            temp->genre=strdup(tempGenre);
            temp->song=strdup(tempTitle);
            temp->played=strdup(tempPlay);
            temp->rating=strdup(tempRating);    

            insertFront(head,temp);

            }

}

我遇到的问题是,当我打印出列表时,所有条目都与从文件中读取的最后一个条目相同。这与strdup()有关,但是我无法在没有访问冲突的情况下将其复制到数据类型。

我可以用来复制从文件中读取的字符串并将它们传递给插入的另一种方法(正确的方法)是什么?

InsertFront

void insertFront(Node **head, Data *data)
{
    Node *temp=makeNode(data);

    if ((*head) == NULL)
    {
        *head=temp;
    }
    else
    {
        temp->pNext=*head;
        *head=temp;
    }

}

数据结构

typedef struct data
{
    char *artist;
    char *album;
    char *song;
    char *genre;
    char *played;
    char *rating;
    char *mins;
    char *secs;
}Data;

测试文件

snoop
heartbeat
swiggity
rap
03
10
25
4
hoodie
cakeboy
birthday
hiphop
02
53
12
5

2 个答案:

答案 0 :(得分:1)

您为所有行使用相同的temp实例。分配应该进入循环内部,理想情况是在确定已成功读入整个条目之后。

顺便说一句,feofnot a good way to control input loops。您应该检查fscanf的返回值。

while (1) {
    if (fscanf(file,"%s",tempAlbum) < 1 ) break;
    if (fscanf(file,"%s",tempArtist) < 1) break;
    // ...

    temp = (Data *) malloc(sizeof(Data));

    temp->album=strdup(tempAlbum);
    temp->artist=strdup(tempArtist);
    // ...

    insertFront(head, temp);
}

请注意,只有在读取整个记录后才会分配新节点。

还有其他方法可以改进代码。例如,对于包含数字数据的字符串,您的缓冲区非常短。如果有一条线路滑落并且您将更长的线路读入这么短的缓冲区怎么办?此外,您的输入似乎是顺行的,因此最好使用fgets而不是fscan(f, "%s"),这只会读取“单词”并且会出现带有空格的行的问题。

答案 1 :(得分:0)

虽然(!eof)错了。你可以这样做。

for (;;) {
    ret = fscanf()
    if(ret == EOF) break;
}