简体   繁体   中英

reading a csv file into struct array

I'm beginning to code in C. My code is as follows:

#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..

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.

我的控制台上的输出

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.
What you do is just point them to tmp(buf) .

So what you do in printBookList() is just print same string block, while ID is OK since it's not pointer.

To solve this, allocate space for them, you can use strdup(), but make sure to free them.

In the while loop:

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 = strtok(NULL, ";");
 books[i].name = tmp;

You should allocate memory for each struct of the array and then use strcopy.

You can find an explanation of differences between strcpy and strdup here: strcpy vs 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.

Try using strdup instead, as in:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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