如何在c中通过strtok复制返回的令牌

How to copy the returned token by strtok in c

当我尝试按照本论坛其他答案的建议通过 strcpy 复制 strtok 时。我没有得到相应的号码。文件格式在每一行上类似于 43,789,127.0.0.1。但是我在 temp[2] 位置得到 127 应该是 127.0.0.1 。我在这里错过了什么?

FILE *f = fopen("somefile", "r");
char *temp[3];
temp[0] = malloc(20);
temp[1] = malloc(20);
temp[2] = malloc(20);
const char s[1] = ",";
char *pch;
if(f != NULL)
{
  char line[1024];
  while(fgets(line, sizeof line, f) != NULL)
  {
    pch = strtok(line, s);
    for(int i = 0; i<3; i++)
    {
      strcpy(temp[i],pch);
      pch = strtok (NULL, s);
    }
  }
  fclose(f);
} else 
{
  perror("somefile");
}
for(int i = 0; i<3; i++)
{
  printf ("%s\n",temp[i]);  
}

s 不是正确的 C 字符串:const char s[1] = ","; 将其定义为大小为 1,没有空终止符。

改用这个:

const char *s = ",";

请注意,少于 2 个逗号的行将导致程序出现未定义的行为,因为您没有检查 strtok() returns 非 NULL 指针。这是使用 sscanf() 的替代方法:

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("somefile", "r");
    char temp[3][20];
    if (fp != NULL) {
        char line[1024];
        while (fgets(line, sizeof line, fp) != NULL)  {
            if (sscanf(line, "%19[^,],%19[^,],%19[^\n]", temp[0], temp[1], temp[2]) == 3) {
                printf("%s\n%s\n%s\n\n", temp[0], temp[1], temp[2]);
            }
        }
        fclose(fp);
    }
    return 0;
}

但是请注意,上面的代码将无法解析带有空字段的行,例如 ,,,因为 sscanf() 需要 %[^,] 转换说明符的非空字符串。

另请注意,strtok() 也不适合此类解析,因为它将分隔符序列视为单个分隔符,这对于白色 space 是可以的,但对于 , 可能不正确.

以下建议代码:

  1. 干净地编译
  2. 一致缩进
  3. 水平和垂直间距适当
  4. 更正了已发布代码中的所有已知问题
  5. 正确检查并处理错误
  6. 正确显示文件中所有行的参数
  7. 消除不需要的变量

现在是代码

#include <stdio.h>   // fopen(), fclose(), fgets(), perror()
#include <stdlib.h>  // exit(), EXIT_FAILURE
#include <string.h>  // strtok(), strcpy()

#define MAX_LENGTH     20
#define MAX_PARAMETERS 3

int main( void )
{
    FILE *f = fopen( "somefile", "r" );
    if( !f )
    {
        perror( "fopen to read somefile failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    char *temp[ MAX_PARAMETERS ];

    if( NULL == ( temp[0] = malloc( MAX_LENGTH ) ) )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }

    if( NULL == ( temp[1] = malloc( MAX_LENGTH ) ) )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }

    if( NULL == ( temp[2] = malloc( MAX_LENGTH ) ) )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }

    char line[1024];
    while( fgets(line, sizeof line, f) )
    {
        int i;
        char *pch = strtok( line, "," );

        for( i = 0; i<3 && pch; i++ )
        {
            strcpy( temp[i], pch );
            pch = strtok ( NULL, "," );
        }

        if( MAX_PARAMETERS != i )
        {
            printf( "failed to extract all parameters from line: %s\n", line );
        }

        else
        {
            for( int j = 0; j<MAX_PARAMETERS; j++ )
            {
                printf( "%s\n", temp[j] );
            }
        }
    }

    fclose( f );
} // end function: main