对此c函数的任何更好的建议都是copyString,concatString
我被要求制作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.世界人物
谢谢。
错误:
strlen
返回不包括 nul终止符的长度,因此您分配的所有大小都太小。
在if (strlen(*strDst) != length)
为false(即长度相等)的情况下,泄漏旧缓冲区。
realloc
和malloc
都可以失败,你应该能够编写代码来应对。
使用realloc
的正确方法是:
char *newbuf = realloc(oldbuf, newsize); if (newbuf == NULL) { // handle the error somehow, and note that oldbuf is still allocated } else { oldbuf = newbuf; }
“以某种方式处理错误”可能需要决定做什么,这取决于你的两个函数的文档说它们在失败时做了什么。 如果它没有说那么它应该。
(Picky) 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; }
除了Steve Jessop在他的回答中提到的内容,你的来源中没有错误但是缺失:
- validation输入参数
- 通过错误值返回错误(例如,作为函数的整数返回码,而不是
void