简体   繁体   English

将csv文件读入struct数组

[英]reading a csv file into struct array

I'm beginning to code in C. My code is as follows: 我开始用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;
    }

}

The problem is, that after readBookFile() ends, the Array of my struct is full of the last value of the input file.. 问题是,在readBookFile()结束之后,我的结构的Array充满了输入文件的最后一个值。

My input file is: 我的输入文件是:

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

so in the readBookFile function the printf returns the correct values, but in the printBooksList() function all values seem to have changed to the last line of my inputfile. 因此在readBookFile函数中,printf返回正确的值,但是在printBooksList()函数中,所有值似乎都已更改为输入文件的最后一行。

我的控制台上的输出

Can anyone explain this to me and maybe point me in the right direction? 有人可以向我解释一下,也许可以指出正确的方向吗?

Thanks a lot Hagbart 非常感谢哈格巴特

The problem is your struct: 问题是您的结构:

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

name, dateIn, dateOut are "pointer", they are just point to something, you're not allocating spaces for them. name,dateIn,dateOut是“指针”,它们只是指向某物,您没有为它们分配空间。
What you do is just point them to tmp(buf) . 您要做的只是将它们指向tmp(buf)

So what you do in printBookList() is just print same string block, while ID is OK since it's not pointer. 因此,您在printBookList()中所做的只是打印相同的字符串块,而ID是确定的,因为它不是指针。

To solve this, allocate space for them, you can use strdup(), but make sure to free them. 要解决此问题,请为它们分配空间,可以使用strdup(),但请确保释放它们。

In the while loop: 在while循环中:

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

you are copying into the memory location of buffer new contents from file. 您正在将文件中的新内容复制到缓冲区的内存位置。 As tmp points to a certain point in the buffer, its contents are being replaced too. 当tmp指向缓冲区中的某个点时,其内容也将被替换。

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

You should allocate memory for each struct of the array and then use strcopy. 您应该为数组的每个结构分配内存,然后使用strcopy。

You can find an explanation of differences between strcpy and strdup here: strcpy vs strdup 您可以在此处找到strcpy和strdup之间差异的解释: strcpy与strdup

The reason is that in something like 原因是在类似

books[i].name = tmp;

You're not actually copying a string from tmp into books[i].name : you just make both point to the same location - somewhere into the buf buffer. 您实际上并没有将tmp的字符串复制到books[i].name :只需将两个books[i].name都指向同一位置-在buf缓冲区中的某个位置。

Try using strdup instead, as in: 尝试改用strdup ,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM