需要优化以下split()函数代码

时间:2014-05-20 13:52:46

标签: c optimization cstring

问题陈述:

想要一个优化的分割功能,它将在字符串中搜索给定的字符,并在字符前后将字符串拆分为2个子字符串

示例:

s1 = strdup("XYZ@30");
s2 = split(s1,"@");
Should get following output.
s1 = "XYZ"    
s2 = "30"

我写了下面的split(),但有人可以帮我优化它。

char * split(char *str1, char *ch)
{
    int i=0;
    char *str2;
    if(!(str1 && ch))
        return NULL;
    else
    {
        str2 = strdup(str1);
        while('\0'==str2)
        {
            if(*str2==*ch)
            {
                i++;
                str1[i]='\0';
                return (++str2);//If the ch is last in str1, str2 can be NULL    
            }
            str2++;
        }
    }
    return NULL;
}

5 个答案:

答案 0 :(得分:1)

不要使用strdup;只需要str2指向分割字符后的字符。

答案 1 :(得分:1)

在优化思路之前,请先确保您的代码是正确的。

在随地吐痰功能中,您在strdup之后执行,这不是标准C,但您的课程假设您拥有它。

while('\0'==str2)
{
  // some splitting logic
}

您永远不会以这种方式进入循环,因为str2的类型为char*

您必须将条件更改为:

while(*str2 != '\0')

实际上说,虽然我们还不在str2的末尾,但是进入循环!

Why strdup is considered evil?

我建议您关注代码错误的原因,而不是复制粘贴在互联网上找到的解决方案。

答案 2 :(得分:0)

诀窍在于您首先要查找分割点的索引,并将其替换为\ 0,并将s2指向下一个字符。这就是你需要做的一切。

char * split(char *str1, char *ch)
{
    int i=0;
    char *str2;
    if(!(str1 && ch))
        return NULL;
    else
    {
        while(str1[i] != *ch) i++; // Get i into position
        /* Make sure i+1 is still in bounds here */
        str2 = str1 + i + 1; // Point str2 to the next character
        str1[i] = '\0'; // Replace the delimiter with \0 to null-terminate s1
    }
    return NULL;
}

但是你也想做一些错误检查并确保,例如,如果\ 0是分隔符,假定你没有将s2指向越界内存。

答案 3 :(得分:0)

char *split(char *str, char ch){//call : s2 = split(s1, '@');
    char *p = strchr(str, ch);
    if(p){
        *p = '\0';
        return p+1;
    }
    return NULL;
}

答案 4 :(得分:0)

  • 您的程序没有按照您的意愿执行,因此请在尝试优化任何内容之前先解决此问题。
  • 为了提高程序的效率,您需要知道分配的字符串的总大小。您需要字符串长度,然后为空终止分配字符串长度+ 1。
  • 事实证明,strdup只是strlen,malloc和strcpy函数的包装器。同时,请注意strdup是100%多余的非标准功能,因此不应使用。
  • 由于上述原因,用strlen,malloc,memcpy替换strdup(memcpy比strcpy略快)。在字符串末尾手动添加空终止字符。
  • split函数应调用strstr函数来检测子字符串的出现(如果有)。
  • 如果检测到子字符串,则需要准确分配

    [original string length] - [index of sub string] + [1 byte null termination]
    

    然后使用memcpy()将子字符串复制到分配的内存块中。

  • 保留原始字符串,但是在找到子字符串的位置将其终止。或者,您也可以为此分配内存并制作硬拷贝,但请注意,分配/重新分配是此程序中的瓶颈(如果存在任何瓶颈......)。

  • 处理未找到子字符串的情况。

  • 您不需要检查传递的参数是否为NULL,以确保调用者负责,而不是函数。