使用strtok_r创建C split函数 - 比如perl和awk

时间:2014-10-20 11:48:17

标签: c gcc

我正在尝试使用split中的perlawk编写我自己的strtok_r函数,C创建数组以及返回数字在数组中的元素,我尝试了一些东西,但我没有得到正确的动态内存分配的概念,请有人纠正我,也请发表评论。

我相信strdup会照顾内存分配吗?

错误:分段错误(核心转储)

这是我到目前为止所尝试的

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>


 int split(char * str, char **fields, const char *sep)
 {
    char *copy = strdup(str), *tmp, *word;     
    int count=0;

    word = strtok_r(copy, sep, &tmp);
    while(word)
    {
                word=strtok_r(NULL, sep, &tmp);
        fields[count] = strdup(word);
        count++;    
    }

    return count;   
 }

 int main()
 {
         char string[80]="a,b,c,d,e,f,g,h,i,j,k,l"; 
         const char *sep = ","; 
         char **cols;  int i;           
     cols = malloc(strlen(string)+1*sizeof(char *));
    printf("%s\n",string);
    int n = split(string,cols,sep);
    printf("%s\t%d\n",string,n);

    for(i=0; i<n; i++)printf("%s\t%s\n",string,cols[i]);
    free(cols);

    return 0;
 }

提前致谢所有志愿者

1 个答案:

答案 0 :(得分:1)

你有很多初学者错误:

1)为cols分配内存,例如。在致电main()之前split()

cols=malloc(sizeof *cols * 256); 

根据需要调整数字256,或根据编号计算数字。你在string中的“,”。

2)你的循环部分是错误的,因为你在检查NULL或存储前一个标记之前再次标记

  while(word)
    {
        word=strtok_r(NULL, sep, &tmp);
        fields[count] = strdup(word);
        count++;    
    }

将标记化作为循环中的最后一个语句:

  while(word)
    {
        fields[count] = strdup(word);
        count++;    
        word=strtok_r(NULL, sep, &tmp);
    }

3)您还应该在copy之前释放split(),然后再返回。否则,你的程序会有内存泄漏。请记住strdup为您分配内存(并且您应该检查它是否也返回NULL),但是您负责free它。

free(copy);

同样适用于为cols[*]分配的内存。即在main()中打印字符串后,执行:

for(i=0;i<n;i++) 
  free(cols[i]);

虽然,在程序终止之前并不是必须释放内存(因为大多数现代操作系统都会解除分配),但清理自己是一种很好的做法。

4)使用main()的标准原型,例如:int main(int argc, char*argv[])int main(void)