我正在尝试编写自己的split
功能类似于 perl
和awk
使用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/