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;
}
You are not checking argc
and derefencing args[1]
and args[2]
.
You never use number
.
Try this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main( int argc, char * argv[] ) {
printf("Starting program\n");
if( argc < 2 ) {
return 1;
}
FILE * fp = fopen( argv[1], "r");
if( fp == NULL ) {
perror( argv[1] );
return 1;
}
char int_array[1000];
if( fgets( int_array, 1000, fp )) {
int nums[1000];
int i = 0;
char * token = strtok(int_array, " ");
while( token ) {
nums[i++] = atoi(token);
token = strtok(NULL, " ");
}
printf("0: %i\n", nums[0]);
printf("1: %i\n", nums[1]);
printf("%d: %i\n", i-1, nums[i-1]);
}
return 0;
}
Execution:
aubin@Breizh-Atao ~/Dev/C $ gcc parsing.c -o parsing
aubin@Breizh-Atao ~/Dev/C $ echo 1 2 3 4 5 6 7 8 9 10 11 >parsing.txt
aubin@Breizh-Atao ~/Dev/C $ ./parsing parsing.txt
Starting program
0: 1
1: 2
10: 11
aubin@Breizh-Atao ~/Dev/C $
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.