如何通过c中的strtok复制返回的标记

时间:2017-05-03 21:17:49

标签: c strtok

当我尝试按照此论坛上其他答案的建议将strtok复制到strcpy时。我没有得到相应的号码。每个特定行上的文件格式类似于这个43,489,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]);  
}

2 个答案:

答案 0 :(得分:6)

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

请改用:

const char *s = ",";

请注意,少于2个逗号的行将导致程序具有未定义的行为,因为您不检查strtok()是否返回非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()对于此类解析也不合适,因为它将分隔符序列视为单个分隔符,对于空格而言可以,但,可能不正确。

答案 1 :(得分:1)

以下提议的代码:

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

    #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