使用fgets和strtok_r的奇怪行为

时间:2012-03-02 17:52:06

标签: c fgets strtok

这是我的代码:

#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;
}

此处有文件students.txt:http://pastebin.com/wNpmXYis

我不明白为什么输出不正确,正如我预期的那样。 我用一个循环用 fgets 读取每一行,然后我有一个由 [Name Surname] 组成的刺痛,我想把它分成两个不同的字符串( [name] [surname] )使用 strtok_r 。我尝试使用静态字符串并且效果很好但是如果我从FILE中读取了很多字符串,则输出不正确,如下所示:

http://pastebin.com/70uPMzPh

我的错在哪里?

2 个答案:

答案 0 :(得分:4)

为什么使用for循环? ...

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 );
  }
}

答案 1 :(得分:2)

你从零开始

unsigned int i = 0;

然后你增加它:

++i < 2; 

您永远不会将 i 设置为零,事实上,对于文件中的每一个新行,再次继续递增 i 。在您的输入文件中有14个名称,我希望 i 可以达到大约14.
(或者可能是13或15,具体取决于具体逻辑)。< / p>

所以这一行:

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

最终将 strtok 结果放入tokens[2..15]。但只有tokens[0]tokens[1]有效。其他一切都是 未定义的行为

答案:当您阅读新文件时,请务必将 i 重置为零。

相关问题