使用 strtok_r 创建 C split 函数 - 就像 perl 和 awk

标签 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) 为cols分配内存,例如在调用 split() 之前的 main() 中:

cols=malloc(sizeof *cols * 256); 

根据需要调整数字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) 返回之前,您还应该在 split() 中释放 copy 。否则,你的程序将会出现内存泄漏。请记住,strdup 会为您分配内存(您还应该检查它是否返回 NULL),但您有责任释放它。

free(copy);

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

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

虽然,在程序终止之前释放内存并不是绝对必要的(因为大多数现代操作系统无论如何都会释放它们),但清理自己是一个很好的做法。

4) 对 main() 使用标准原型(prototype),例如:int main(int argc, char*argv[])int main(无效)

关于使用 strtok_r 创建 C split 函数 - 就像 perl 和 awk,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26464957/

相关文章:

c - 使用 RSA_public_encrypt 加密/解密没有填充的单个八位字节

c - gcc 的 __sync 和 __atomic 内在函数有什么区别

c - GCC 语句表达式问题

c - 打开 DOS 窗口并从 DLL 中喷出调试消息

c - 内核模块内存访问

连接功能时常失效?

linux - 有效地在 ELF 文件中添加新部分

c - 使用 exec() 函数在 C 中调用 Linux 命令

gcc - 在 gcc 中禁用除少数警告之外的所有警告

php - linux 正确标志传递 gcc mcrypt.h 位置