#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char* getfield(char* line, int num) {
const char* tok;
for (tok = strtok(line, ",");
tok && *tok;
tok = strtok(NULL, ",\n"))
{
if (!--num)
return tok;
}
return NULL;
}
int main()
{
FILE* stream = fopen("b.csv", "r");
char line[1024];
char *pstr;int num;
const char* value;
while (fgets(line, 1024, stream))
{
char* tmp = strdup(line);
//printf("Field 3 would be %s\n", getfield(tmp, 3));
value=getfield(tmp, 3);
num =strtol(value,&pstr,10);
printf("Field 3 would be %d\n", num);
// NOTE strtok clobbers tmp
free(tmp);
}
}
/* b.csv
301,36,15
302,88,75
/ / my output
Field 3 would be 15
Field 3 would be 75
*/
issue is : /* b.csv
301,36,15
302,88,
,,,34
if the the table is broken as above "strtok" returns NULL ,and so "strtol" gives "segfault"..how to resolve it ?
Here the main issue is if 2nd is not present, it treats 3rd as a second and gives segfault !! for example in a 3rd row of b.csv ",,,34" is there means 3rd value is present, but It behaves like "34" is a 1st value and 2nd and third are respectively NULL !!
Why can't you just check the
value
that you get fromgetfield(tmp, 3);
forNULL
and not callstrtol
ifNULL
is returned? Another way to get around is make astatic char* not_found = "";
ingetfield
and return address to it instead ofNULL
, thenstrtol
will not segfault.UPDATE
Since i found that
strtok
really is helpless in this situation i tried to write code that does the same withstrchr
:This worked on input file:
The code returns
0
if nothing is found, you can change that, and the result is dynamically allocated. I hope this helps, the lesson for me is - avoid C when parsing strings :D