1

I am currently programming a c program which gets text files as input. in every line I am getting a known ahead n float numbers, separated with comma. example line:

0.92,0.21,0.98,1
0.23,0.37,0.29,-1
0.22,0.35,0.63,1
0.14,0.89,0.78,-1
0.26,0.42,0.67,1
0.01,0.77,0.92,-1
0.67,0.12,0.59,-1

I need to put the numbers in an array. here is part of my code:

strcpy(tmp_line,strtok (line,","));
for(int j = 0;j < n + 1; j++)
{
            vec.arr[j] = atof(tmp_line);
            strcpy(tmp_line,strtok (NULL, ","));
}

I don't know why, when I use clion, in the end of the loop the program just stops running. when I use codeblocks, it give this message

PROCCES RETURNED (0Xc0000005)

which means we are using memory that we cannot access.

help? anybody?


a few notes: vec is a Vector struct. a Vector struct contains a 75 long array and a (int) tag. we use the first n cells of the array and put the tag (+ or - 1) in the n+1 cell (and the tag part).

tmp_line is a char array contains the current line.

P.P
  • 117,907
  • 20
  • 175
  • 238

3 Answers3

1

As I see your code, the problem appears to be in

 strcpy(tmp_line,strtok (NULL, ","));

inside the for loop. Once finished tokenizing, strtok() will return NULL which is considered invalid parameter for strcpy().

You should break down the statement, collect the return value of strtok() into a temporary pointer variable, check against NULL and if not NULL, perform the strcpy().

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

Okay, you need to look at the documentation for strtok, first of all. What strtok returns is a char * to the next token. On the first call, it stashes the string, then on each call after that with NULL as the argument it gets the next string.

so, the canonical code would be

char * my_string = "this is a blank delimited string";
char * tok;
tok = strtok(my_string, " ");
while(tok != NULL){
  /* do something with the string */
  printf("Token: %s\n", tok);
  tok = strtok(NULL, " ");
}

It's hard to tell where your code is going wrong, but at the very least that strcpy is unnecessary. It's also, from what you're saying, a problem that you're doing a strcpy on top of the string that contains the current line, which means you are mashing the string that strtok is trying to tokenize; this is probably the source of the memory error.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • Passing a string literal to `strtok()` is *undefined behaviour*. – P.P Aug 05 '15 at 15:53
  • Nonsense. In fact the example in the canonical POSIX man page uses a string constant. http://pubs.opengroup.org/onlinepubs/009695399/functions/strtok.html – Charlie Martin Aug 05 '15 at 18:19
  • Just because the manual you happen to find on the internet contains a wrong example, it doesn't make it right. Perhaps, you should read either C standard or search on the internet before emphatically calling it *nonsense*. – P.P Aug 05 '15 at 18:26
  • Look again. POSIX standard. – Charlie Martin Aug 05 '15 at 18:30
  • So what? POSIX documentation writers never make a mistake? What's your point? – P.P Aug 05 '15 at 18:31
0

Your loop counter is probably wrong. You say you only have n floats but it loops for n+1 times. You don't need to count the number of floats either. You don't need tmp_line either. As you tokenize, you can count the number of floats. So it boils down to this:

j = 0;
for(char *tmp = strtok (line,","); tmp ; tmp = strtok (NULL, ","))
{
   vec.arr[j] = atof(tmp);
   j++;
}
// 'j' number of tokens found in this line

This would also save you from worrying about whether you pass valid strings to strcpy() (as you don't need at all :)

There are other things you need to consider:

1) How to handle if the line contains uneven number of floats.
2) Whether arr has enough storage for as many floats in each line.
3) atof() doesn't report errors on conversion. You would be advised to use strtof() or strtod() for detecting conversion failures.

P.P
  • 117,907
  • 20
  • 175
  • 238