arrayscstringfile-handling

How to properly read a file into an array?


for a larger project I've been experimenting with file handling in C. Essentially, what I would like to do is: load a one-dimensional string of numbers from a text file into an array which is a part of a struct in my program.

First a sample of my code:

static struct mapData {
    int* walls;
    // ...
};

static struct mapData currentMap;
// ...
currentMap.walls = malloc(mapSize * sizeof(int));
fileToArray(wallsAdress, mapSize, 1, currentMap.walls, &returnedArrayLength);
// ...
void fileToArray(char *fileName, int lineSize, int readLine, int *array, int *returnedArrayLength) {
    FILE *file;

    file = fopen(fileName, "r");

    if (file == NULL) {
        printf("Error opening file");
        return;
    }

    bool keepReading = true;
    int currentLine = 1;
    char lineBuffer[2048];

    while (keepReading == true) {
        fgets(lineBuffer, sizeof(lineBuffer), file);

        if (currentLine == readLine) {
            keepReading = false;
            char *token = strtok(lineBuffer, " ");
            int i = 0;

            while (token != NULL && i < lineSize) {
                array[i++] = atoi(token);
                token = strtok(NULL, " ");
            }

            printf("Returned array length: %d from line: %d\n", i, readLine);
            for (int j = 0; j < i; j++) {
                printf("%d", array[j]);
            }
            printf("\n");

            if (returnedArrayLength) *returnedArrayLength = i;
        }
        currentLine++;
    }

    fclose(file);

    return;
}

When printing out currentMap.walls however, I get a bunch of garbage numbers. When debugging my code, I found that the lineBuffer does in fact receive the correct information from the file in fgets(). It would seem something is going wrong when transferring the information from char lineBuffer to int* walls. As you can see I also added an additional tool for debugging at the end of fileToArray which ends up printing out this:

Returned array length: 1 from line: 1
1102871301
Returned array length: 1 from line: 1
0
Returned array length: 1 from line: 1
1272272213
Returned array length: 1 from line: 1
-477218589

Solution

  • First of all, thank you for the feedback and I apologize for perhaps not being as clear as I could have been nor giving as much information as I should have. Indeed, the critical fault lied in the requested source file. Originally the .txt file looked something like this:

    555555555555553333333333333333310100000000000000000111000001333333333333333333334333343
    

    When coming up with the method I naïvely just copied what was given to me rather than fully understanding what was going on. Even a surface level understanding of strtok() would have likely prevented this simple mistake. strtok()'s second input is a delimiter which the function needs to properly separate the string of chars into ints, after all how would it know if the first number was 5 or 5555? Now knowing this I edited the file to look more like this:

    5 5 5 5 5 5 5 5 5 5 5 5 5 5 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 3 3 3 3 4 3
    

    Now, strtok(lineBuffer, " ") properly separates and stores the numbers as individual integers rather than one enormously long number which I believe is what was happening.

    Now, as far as I'm aware everything is working as intended with that fix to the file. However--and maybe this is a question for a separate post--Many commented or at least illuded against using fgets() as a method to read a file. Initially why I chose this was so that I could perhaps store multiple arrays in one file instead of needing a separate file I could just choose which line to read in one file. I was thinking this might make things cleaner, but if this can be achieved just as well and with better reliability using a different method, I'd be open to it.