I'm using strtok() to parse each integer and place it into int nums[1000]
. The file will always follow the format of:
the first line has the numbers for the array, each separated by spaces. No more than 10 numbers will be on the line. Nothing is in the file after the first line.
printf("Starting program\n");
char file_name[100];
strcpy(file_name, args[1]);
char number[100];
strcpy(number, args[2]);
FILE *fp;
fp = fopen(file_name, "r");
if (fp == NULL) {
printf("Error opening file\n");
}
char int_array[1000];//
int nums[1000]; //storing the integers without spaces
int i = 0; //for indexing the array to save the integers
while (fgets(int_array, 1000, fp) != NULL) {
printf("%s\n", "test");
puts(int_array); // prints out `1 2 3 4 5...`
char *token;
token = strtok(int_array, " ");
nums[i] = atoi(token);
while (token != NULL) {
token = strtok(NULL, " ");
nums[i] = atoi(token);
//puts(token); Token gets printed out correctly.
}
}
printf("%i\n", nums[i]); // this gives segmentation fault
printf(nums) // also gives seg fault
I cannot figure out why I am getting seg fault.
There are multiple problems in your code, the main issue is you test token
before scanning the next token:
while (token != NULL) {
token = strtok(NULL, " ");
nums[i] = atoi(token);
}
You should instead do this:
while ((token = strtok(NULL, " ")) != NULL) {
nums[i] = atoi(token);
}
Other issues:
argc > 1
before accessing argv[1]
in strcpy(file_name, args[1]);
, potentially invoking undefined behavior.argv[1]
to fopen
or use a pointer: char *filename = argv[1];
fopen()
failed, but do not exit the function... fgets()
has undefined behavior for a null stream pointer.strtok()
can return NULL
even for the first call. Always check the return value before passing it to atoi()
.i
becomes too large. You should stop reading the input file if i
reaches 1000
.nums
array to printf
is incorrect: printf(nums)
should not even compile, or at least generate meaningful warnings.Note that you do not need to use strtok()
at all. strtol()
can parse a number and update a pointer to point past the number.
Here is how to use that:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
printf("Starting program\n");
if (argc < 2) {
fprintf(stderr, "missing command line argument\n");
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "cannot open %s: %s\n", argv[1], strerror(errno));
return 1;
}
char buf[1000];
int nums[1000];
int i = 0;
while (fgets(buf, sizeof buf, fp)) {
char *p = buf;
char *q;
for (; i < 1000; i++) {
nums[i] = strtol(p, &q, 0);
if (q == p) {
/* no more numbers */
break;
}
p = q;
}
}
fclose(fp);
for (int j = 0; j < i; j++) {
printf("%d ", nums[j]);
}
printf("\n");
return 0;
}