首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >strcat实现

strcat实现
EN

Code Review用户
提问于 2016-12-13 22:55:54
回答 3查看 3K关注 0票数 7

我用C语言编写了我自己的strcat实现。

代码语言:javascript
复制
char* my_strcat(char *str1, char *str2)
{
   int len_str1 = 0, len_str2 = 0, len_str3; 

   for (int i = 0; str1[i] !='\0'; i++)
   {
      len_str1++;
   }

   for (int i = 0; str2[i] != '\0'; i++)
   {
      len_str2++;
   }

   len_str3 = len_str1 + len_str2;
   char* str3 = malloc(len_str3*sizeof(char));

   for (int i = 0; i < len_str1; i++)
   {
      *(str3+i) = *(str1+i);
   }

   for (int i = 0; i < len_str2; i++)
   {
      *(str3+i+len_str1) = *(str2+i);
   }

   return str3;
} 

我正在寻找任何可以改进的东西:可读性,效率,代码清理,bug,.

EN

回答 3

Code Review用户

回答已采纳

发布于 2016-12-13 23:09:29

  1. 最明显的是,尽管这与标准strcat函数的原型相匹配,但它的工作方式非常不同。标准的strcat函数不分配内存。
  2. 在为新字符串分配内存时,不考虑终止NUL字符。
  3. 从(2)开始,实际上并不终止新字符串。
  4. sizeof(char)的值被定义为1,因此您实际上不需要乘以该值。
  5. 您对空格的使用略有不一致,在第一个循环中,在!=之后没有空格,但是在第二个循环中。
  6. 虽然*(str3+i)的使用是有效的,而且没有错误,但是使用str3[i]更易读,也更常见。符合MISRA标准的函数必须使用后者。
  7. 您可以将int len_str3的声明向下移动到计算其值的位置,这样就有了int len_str3 = len_str1 + len_str2;。这样,你就不会在顶部有一个未初始化的变量了。
票数 15
EN

Code Review用户

发布于 2016-12-13 23:23:55

通过使用memcpy(),可以使您所拥有的代码简洁高效。在您的函数原型中使用consts不会有什么害处。此外,如果要使用malloc()分配内存,则应该在使用它之前检查结果。并确保包含NUL终结者的空间!

my_strcat()代码的第一个版本中,分配错误是致命的,程序将使用EXIT_FAILURE进行exit。但是Toby指出,对于库函数来说,这是一个糟糕的选择。在这种情况下,最好返回NULL,并让调用方决定如何处理错误。这使得代码更加简洁,更像是库函数的工作方式。下面的新版本尝试malloc一些新字符串的内存,将结果存储在str中。如果分配成功,则复制输入字符串。如果分配失败,str是一个NULL指针,不会发生复制,并且从函数返回NULL。然后调用方负责处理和记录错误。

代码语言:javascript
复制
#include <stdlib.h>
#include <string.h>

char * my_strcat(const char const *str1, const char const *str2)
{
    size_t len1 = strlen(str1);
    size_t len2 = strlen(str2);

    char *str = malloc(len1 + len2 + 1);

    if (str) {
        memcpy(str, str1, len1);
        memcpy(str + len1, str2, len2 + 1);
    }

    return str;
}

请记住,在退出程序之前,您必须释放通过调用my_strcat()分配的内存。不分配内存并且在精神上更接近标准库版本的版本可能使用memcpy()将第二个字符串的内容复制到第一个字符串的末尾。使用restrict类型限定符(在标准库版本中)表明tofrom不重叠。这是推荐的(对于C99和更高版本),因为在重叠数组与memcpy()之间复制是未定义的行为,而且restrict限定符允许编译器进行优化。

代码语言:javascript
复制
char * strcat(char *restrict to, const char *restrict from)
{
    size_t to_len = strlen(to);
    size_t from_len = strlen(from);

    memcpy(to + to_len, from, from_len + 1);

    return to;
}

请注意,在这里,与标准库版本一样,调用方有责任确保to中有足够的空间容纳其他字符,包括一个NUL终止符。

票数 8
EN

Code Review用户

发布于 2016-12-14 11:05:24

人们已经说了很多,但这一点还没有,至少没有明确规定:

不重新发明车轮

int len_str1 = 0,len_str2 = 0,len_str3;for (int i= 0;str1我 !='\0';i++) { len_str1++;}

您的目标是实现您自己的自定义strcat。这并不是为了实现您自己的自定义strlen,所以这应该是

代码语言:javascript
复制
size_t len_str1 = strlen(str1);

str2也是如此。

票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/149812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档