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