将csv文件读入struct数组

时间:2013-11-26 09:14:27

标签: c arrays struct malloc

我开始用C编码。我的代码如下:

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

#define MAX_STR_LEN 256
#define MAX_BOOKS 256

struct book{
    int ID;
    char *name;
    char *dateIn;
    char *dateOut;
};

struct book books[MAX_BOOKS];

/* PROTOTYPE OF FUNCTIONS */
int readBookFile();
void printBookList();


int main(int argc, char **argv)
{   
    int isOK = 0;

    isOK = readBookFile();

    printBookList();

    system("pause");
    return 0;
}

int readBookFile()
{
    /* FileStream for the Library File */
    FILE *bookFile;

    /* allocation of the buffer for every line in the File */
    char *buf = malloc(MAX_STR_LEN);
    char *tmp; 

    /* if the space could not be allocaed, return an error */
    if (buf == NULL) {
        printf ("No memory\n");
        return 1;
    }

    if ( ( bookFile = fopen( "library.dat", "r" ) ) == NULL ) //Reading a file
    {
        printf( "File could not be opened.\n" );
    }

    int i = 0;
    while (fgets(buf, 255, bookFile) != NULL)
    {
        if ((strlen(buf)>0) && (buf[strlen (buf) - 1] == '\n'))
            buf[strlen (buf) - 1] = '\0';       

        tmp = strtok(buf, ";");
        books[i].ID = atoi(tmp);

        tmp = strtok(NULL, ";");
        books[i].name = tmp;

        tmp = strtok(NULL, ";");
        books[i].dateIn = tmp;

        tmp = strtok(NULL, ";");
        books[i].dateOut = tmp;

        //tempBook.ID = atoi(buf);
        printf("index i= %i  ID: %i, %s, %s, %s \n",i, books[i].ID , books[i].name, books[i].dateIn , books[i].dateOut);

        i++;
    }
    //free(buf);
    fclose(bookFile);
    return 0;
}

void printBookList()
{

    int i;
    //i = sizeof(books) / sizeof(books[0]);
    //printf ("%i \n", i);


    for (i = 0; i <= sizeof(books); i++)
    {
        if (books[i].ID != 0)
        printf("index i= %i  ID: %i, %s, %s, %s \n",i, books[i].ID , books[i].name, books[i].dateIn , books[i].dateOut);
        else
            break;
    }

}

问题是,在readBookFile()结束后,我的struct的数组已经满了输入文件的最后一个值。

我的输入文件是:

1;das erste Buch; 12122013; 13122013
2;das Zweite Buch; 12122013; 13122013
3;das dritte Buch; 12122013; 13122013
4;das vierte Buch; 12122013; 13122013
5;das fünfte Buch; 12122013; 13122013
6;das sechste Buch; 12122013; 13122013

所以在readBookFile函数中printf返回正确的值,但在printBooksList()函数中,所有值似乎都已更改为输入文件的最后一行。

the output on my console

任何人都可以向我解释这一点,也许可以指出我正确的方向吗?

非常感谢 Hagbart

3 个答案:

答案 0 :(得分:2)

问题在于你的结构:

struct book{
    int ID;
    char *name;
    char *dateIn;
    char *dateOut;
};

name,dateIn,dateOut是“指针”,它们只是指向某个东西,你没有为它们分配空格。
你做的只是指向 tmp(buf)

所以你在printBookList()中所做的只是打印相同的字符串块,而ID是正常的,因为它不是指针。

要解决这个问题,为它们分配空间,你可以使用strdup(),但一定要释放它们。

答案 1 :(得分:1)

在while循环中:

while (fgets(buf, 255, bookFile) != NULL)

您正在从文件复制到缓冲区新内容的内存位置。由于tmp指向缓冲区中的某个点,其内容也被替换。

 tmp = strtok(NULL, ";");
 books[i].name = tmp;

您应该为数组的每个结构分配内存,然后使用strcopy。

您可以在此处找到strcpy和strdup之间差异的解释: strcpy vs strdup

答案 2 :(得分:0)

原因在于

之类的东西
books[i].name = tmp;

您实际上并未将tmp中的字符串复制到books[i].name:您只需将两者指向同一位置 - 位于buf缓冲区的某处。

请尝试使用strdup,例如:

books[i].name = strdup(tmp);