I have a file, which, at one line has an arbitrary number of numbers to be read as integers. In a minimal, reproducible example, I created a file test.dat
that contains the following line only:
1 2 3 4
I then try to use fgets
and strtok
to achieve this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
FILE* fileptr;
fileptr = fopen("test.dat","r");
char line[500];
char *token;
int array[20];
int i = 0;
fgets(line,300,fileptr);
token = strtok(line," ");
array[i] = atoi(token);
printf("%d\n", array[i]);
i++;
while(token != NULL){
token = strtok(line," ");
array[i] = atoi(token);
printf("%d\n", array[i]);
i++;
}
return 0;
}
But this results in printing 21 lines of 1
's, followed by 632 lines of 0
's. Finally it gives a segmentation fault because the i
grows larger than 20, the allocated space for array
. What I don't understand is why 600+ lines are printed, and why I can never read beyond the number 1
in the file. What am I missing?
Note: I prefer to keep reading from the file with fgets
because this is going to be a simple modification to an existing subroutine that reads an entire file.
A few things:
array
strtok
within the loop is wrong. A continuation of an initial onset of strtok
should specify NULL
as the first argument. See documentation for strtok
for more information and usage examples.An example that addresses these problems is here:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE* fileptr = fopen("test.dat","r");
if (fileptr == NULL)
{
perror("Failed to open file: ");
return EXIT_FAILURE;
}
char line[500];
int array[20];
const size_t max_size = sizeof array / sizeof *array;
size_t i = 0;
if (fgets(line,300,fileptr))
{
char *token = strtok(line," ");
while (i < max_size && token != NULL)
{
array[i] = atoi(token);
printf("%d\n", array[i]);
++i;
token = strtok(NULL, " ");
}
// use array and i for whatever you needed
}
return EXIT_SUCCESS;
}
Output
1
2
3
4