对此c函数的任何更好的建议都是copyString,concatString

时间:2012-11-17 14:21:05

标签: c


我被要求制作2个函数copyString和concatString我做了并实现了它们但是在我得到的输出中我被告知它可以做得更好但从未得到解释如何。
现在它正在杀死我,我能做得更好,所以这里是代码,我很乐意听到任何建议。

void copyString (char **strDst, const char *strSrc)
{
     char *strTmp = NULL;
     int length = strlen (src);
     if (*strDst== NULL) 
     {
        *strDst= malloc (length);   
     }
     else 
     {  
         if (strlen(*strDst) != length)
         {
             strTmp = *strDst;
         }
         *strDst= malloc (length);  
     }
     strcpy (*strDst, strSrc);  
     if (strTmp != NULL)    
         free (strTmp );    
 }

void concatString (char **strDst, const char *cat)
{
     int cat_length = strlen (cat);
     if (cat_length > 0) 
     {  
         *strDst= realloc (*strDst, strlen (*strDst) + cat_length); 
          strcat (*strDst, cat);
     }
}




void main(int argc, char *argv[])
{
    char *str = NULL;
    copyString(&str, "Hello World");
    puts(str);
    copyString(&str,str+6);
    puts(str);
    concatString(&str, " Pesron");
}

输出应如下:
1.你好世界 2.世界
3.世界人士

感谢。

2 个答案:

答案 0 :(得分:4)

错误:

strlen返回排除 nul终结符的长度,因此您分配的所有大小都太小。

如果if (strlen(*strDst) != length)为假,(即长度相等),则泄漏旧缓冲区。

reallocmalloc都可能失败,您应该能够编写代码来应对。

使用realloc的正确方法是:

char *newbuf = realloc(oldbuf, newsize);
if (newbuf == NULL) {
    // handle the error somehow, and note that oldbuf is still allocated
} else {
    oldbuf = newbuf;
}

“以某种方式处理错误”可能需要决定做什么,这取决于你的两个函数的文档说它们在失败时做了什么。如果它没有说那就应该。

(挑剔)int不能保证足够大,以保持字符串的长度。使用size_t(除非你严格禁止使用无符号类型,在这种情况下有ssize_t)。

你可以改进的事情:

没有必要像你那样使用strTmp,你可以立即释放字符串而不是函数的结尾。 [编辑:是的,有需要,似乎要求copyString但不concatString应允许源和目的地重叠。就个人而言,我仍然会略有不同。]

if (strTmp != NULL) free (strTmp );中,测试是多余的,因为使用空指针调用free是有效的,这样做无效。

您在*strDst= malloc (length);中的两种情况下都copyString

main泄漏内存,因为它永远不会释放str

main应该返回int,而不是void

以下是我写它们的方式:

由于您无法更改调用代码以使其检查错误,您必须abort()或在其中写某些内容,它可以调用puts 。由于main函数是在假设调用不能失败的情况下编写的,abort()可能是最不好的解决方案。

如果函数返回指示成功或失败的值,那么调用者可能会更好,但我们受现有调用代码的约束。老实说,为...编程并不是一个完全不切实际的情况。

void concatString (char **strDst, const char *cat) {
    size_t dstlen = *strDst ? strlen(*strDst) : 0;
    char *buf = realloc(*strDst, dstlen + strlen(cat) + 1);
    if (!buf) {
        abort();
    }
    strcpy(buf + dstlen, cat);
    *strDst = buf;
}

void copyString (char **strDst, const char *strSrc) {
    char *buf = malloc(strlen(strSrc) + 1);
    if (!buf) {
        abort();
    }
    strcpy(buf, strSrc);
    free(*strDst);
    *strDst = buf;
}

答案 1 :(得分:0)

除了 Steve Jessop 在他的回答中提到的内容,你的来源中没有错误但是遗漏:

  • 输入参数验证
  • 通过错误值返回错误(例如,作为函数的整数返回码,而不是void