简体   繁体   中英

Strange behaviour using fgets and strtok_r

This is my code:

#define LEN 40
#define STUDLIST "./students.txt"

int main()
{
 FILE * studd;
 char del[] = "" " '\n'";
 char name[LEN], surname[LEN], str[LEN];
 char *ret;
 char *tokens[2] = {NULL};
 char *pToken = str;
 unsigned int i = 0;

 /* open file */
 if ( (studd = fopen(STUDLIST,"r") ) == NULL ) 
 {
   fprintf(stderr, "fopen\n");
   exit(EXIT_FAILURE);
 }

 while((ret = fgets(str, LEN, studd)))
    {
     if(ret)
        {
         for( tokens[i] = strtok_r( str, del, &pToken ); ++i < 2; 
              tokens[i] = strtok_r( NULL, del, &pToken ) );

           strcpy(name, tokens[0]);
           strcpy(surname, tokens[1]);

           printf( "name = %s\n", name );
           printf( "surname = %s\n", surname );
         }
      fflush(studd);
    }
   fclose(studd);

 return 0;
}

Here there is the file students.txt: http://pastebin.com/wNpmXYis

I don't understand why the output isn't correct as I expected. I use a loop to read each line with fgets , then I have a sting composed by [Name Surname] , and I want to divide it in two different strings ( [name] and [surname] ) using strtok_r . I tried with a static string and it works well, but If I read many strings from FILE the output is not correct as you can see here:

http://pastebin.com/70uPMzPh

Where is my fault?

Why are you using for loop? ...

while((ret = fgets(str, LEN, studd)))
{
  if(ret)
  {
    tokens[0] = strtok_r( str, del, &pToken );
    tokens[1] = strtok_r( NULL, del, &pToken );

    strcpy(name, tokens[0]);
    strcpy(surname, tokens[1]);

    printf( "name = %s\n", name );
    printf( "surname = %s\n", surname );
  }
}

You start i at zero:

unsigned int i = 0;

And later you increment it:

++i < 2; 

You never set i back to zero, and in fact, continue incrementing i again for every new line in your file. With 14 names in your input file, I expect i to get to about 14.
(or maybe 13 or 15, depending on the exact logic) .

So this line:

tokens[i] = strtok_r(...);

ends up putting strtok results into tokens[2..15] . But only tokens[0] and tokens[1] are valid. Everything else is undefined behavior .

Answer: Be sure you reset i to zero when you read a new line of your file.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM