tags:

views:

84

answers:

3

Hi there,

I'm trying to load a CSV file into a single dimentional array. I can output the contents of the CSV file, but in trying to copy it into an array I'm having a bit of trouble.

Here is my existing code, which I realise is probably pretty bad but I'm teaching myself:

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

#define MAX_LINE_LENGTH 1024
#define MAX_CSV_ELEMENTS 1000000

int main(int argc, char *argv[])
{
    char line[MAX_LINE_LENGTH] = {0};
    int varCount = 0;
    char CSVArray[MAX_CSV_ELEMENTS] = {0};

    FILE *csvFile = fopen("data.csv", "r");

    if (csvFile)
    {
        char *token = 0;
        while (fgets(line, MAX_LINE_LENGTH, csvFile)) 
        {
            token = strtok(&line[0], ",");
            while (token)
            {
                varCount++;
                CSVArray[varCount] = *token; //This is where it all goes wrong
                token = strtok(NULL, ",");
            }
        }
        fclose(csvFile);
    }
    return 0;
}

Is there a better way I should be doing this? Thanks in advance!

A: 

You are right about the problem line. It is because you are assigning a pointer, not copying the text.

Try here http://boredzo.org/pointers/ for a tutorial on pointers.

Brian Hooper
A: 

It looks like you're trying to put the char * that comes back from strtok into the char array.

I think you want to declare CSVArray as:

char * CSVArray[MAX_CSV_ELEMENTS] = {0};
John Weldon
I don't think the OP wants to do that; he needs to copy the text into the array, not point into the line buffer, which gets overwritten on the following read.
Brian Hooper
You could be right @Brian; I thought that too originally, but if you see that his CSVArray is initialized to the max number of csv *elements*, you could interpret that to mean he intends each slot in the array to be a `char *` to the tokenized string. This would make more sense to me, since copying an already tokenized string would seem wasteful?
John Weldon
@John Yes, I wouldn't want to be too critical of a learner, but it is rather hard to tell what was intended.
Brian Hooper
+2  A: 

*token means dereferencing the pointer token which is the address of the first character in a string that strtok found. That's why your code fills CSVArray with just the first characters of each token.

You should rather have an array of char pointers to point at the tokens, like:

char *CSVArray[MAX_CSV_ELEMENTS] = {NULL};

And then assign a pointer to its elements:

CSVArray[varCount] = token;

Alternatively, you can copy the whole token each time:

CVSArray[varCount] = malloc(strlen(token)+1);
strcpy(CVSArray[varCount], token);
Michał Trybus