创建拆分功能时出错

时间:2014-02-08 02:09:35

标签: c string pointers multidimensional-array

这是一个基于charecter将字符串拆分为字符串数组的函数:

char** split(char c,char* src)
{
    int i=0,size=mystrlen(src);
    int num=count(c,src);
    int foundAt;
    //For example for the string The0red0ruby0read0to0read,there are five occurences of zero
    //so if you used substring and split you would have ten values,but except for the first and
    //last values,every other value would repeat twice,so remove these from 10...to give you 8/2 non-repeating values
    //the formula: 2+(2n-2)/2 ==>2+n-1 ==>count+1
    num=num+1;
            //no malloc/calloc here,let substring take care of this...
    char* res[num];
    while(i<num)
    {
        foundAt=indexof(c,src);
        if(foundAt==0)
        {
            //ignore
            src=substring(src,1,size);
        }
        if(foundAt==-1)
        {
            break;
        }

        if(foundAt>=size)
        {
            //ignore if found at the last charecter or null terminator
            break;
        }   
        res[i]=substring(src,0,foundAt);
        src=substring(src,foundAt,size);
        if(src==NULL)
        {
            break;
        }   
        i++;
    }   
    return res; 
}

这是我尝试使用该功能的方式:

   char* look="Look0here0there0seems0to0be0nothing0here";
char**res=split('0',look);  
printf("The first value is %s\n",res[0]);//=>Look
printf("The third value is %s\n",res[2]);//=>there

使用valgrind运行程序时获得的结果:

   ==6221== Invalid read of size 8
   ==6221==    at 0x4016F9: main (inittest.c:424)
   ==6221==  Address 0xfff0003a0 is just below the stack ptr.  To suppress, use: --workaround-gcc296-bugs=yes
   ==6221== 
   The first value is Look
   ==6221== Invalid read of size 8
   ==6221==    at 0x401719: main (inittest.c:425)
   ==6221==  Address 0xfff0003b0 is just below the stack ptr.  To suppress, use: --workaround-gcc296-bugs=yes
   ==6221== 
   The third value is 

我的助手功能:

 int mystrlen(char* val)
{
    int i=0;
    while(val[i]!='\0')
    {
        i++;
    }
    return i++; 
}

    char* substring(char* src,int start,int end)
{
    int i,size_src=mystrlen(src);
    if(start>size_src|| start<0)
        return NULL;
    if(end>size_src)
        end=size_src;
    //['a','b','c','d'] 1,3 ['b','c']
    //starts at start and reads up to but not including end,the extra charecter in calloc is to add a '\0' there
    int size_res=end-start;
    char* res=calloc(size_res+1,sizeof(char));
    for(i=0;i<size_res;i++)
    {
        res[i]=src[start+i];
    }
    res[i]='\0';
    return res;
}

    int indexof(char c,char* src)
{
    int i=0;
    int size=mystrlen(src);
    for(i=0;i<size;i++)
    {
        if(c==src[i])
            return i;
    }
    return -1;  
}

char* mystrchr(char c,char* src)
{
    int i=0,size=mystrlen(src);
    //must include null charecter
    for(i=0;i<=size;i++)
    {
        if(src[i]==c)
        {
            return src+i;   
        }   
    }
    return NULL;    
}

    int count(char c,char* src)
    {
       int i,size=mystrlen(src);
       int num=0;
       for(i=0;i<size;i++)
       {
          if(c==src[i])
          {
             num++;
          }   
       }
       return num;      
    }

编辑:

我也尝试使用mystrchr替换src直接获取指向字符串的指针,在这种情况下,每次都会调用在零处找到char的条件。

2 个答案:

答案 0 :(得分:0)

我无法清楚地理解你的问题。预定义函数strchr将返回第一次出现的字符位置。这个功能可以帮到你。

答案 1 :(得分:0)

您的res变量驻留在堆栈上,并且在执行您的函数后,此内存将很快被覆盖。你必须动态分配那个内存,例如。

char **res;
res = calloc(num, sizeof(char *));

使用strtok_r

解决问题可能会轻松得多
char *saveptr;

token = strtok_r(stringptr, delim, &saveptr);
while (token) {
    print(token);
    token2 = strtok_r(NULL, delim, &saveptr);
}

您必须注意,这将通过将所有分隔符替换为0个字符来修改输入字符串。