在C中连接字符串-`strcpy(s1 + = strlen(s1),s2)`

时间:2019-01-16 22:32:11

标签: c pointers c-strings

我正在尝试理解“标准C库”中提出的连接字符串的方法。

讨论了如何连接两个字符串s1和s2之后。作者建议对于多个字符串(超过2个),

  

“ ...喜欢strcpy(s1 += strlen(s1), s2)之类的格式,该格式可以节省对字符串的初始部分的重复扫描,甚至是更长的重新扫描...”(第395页)

我无法理解此代码段。我的理解是,他为指针添加了s1的长度,以便将Null字符的索引传递给strcpy,因此strcpy不必遍历s1即可找到Null字符,并且可以开始复制s2转换为s1,对吗?

如果我的理解是正确的,那么当代替strcpy时,strlen仍将不得不循环遍历字符串以确定其长度吗?

2 个答案:

答案 0 :(得分:5)

是:s1 += strlen(s1)将为您提供指向终止0的指针,因此strcpy(..., s2)的工作方式类似于strcat()-将s2附加到{{1} }(假设s1中有足够的空间。请注意,s1不会“通过s1循环来找到Null”-它只是在给定strcpy()的位置上找到了Null但是。

优化的关键是我们实际上正在更改strcat的{​​{1}}(最好复制原始值)。因此,我们只考虑添加的最后一个字符串的长度,而不考虑第一个字符串开头的长度(这是+=解决方案的作用)。

答案 1 :(得分:1)

strcpy(s1 + strlen(s1),s2) 确实将重复计算的s1的重新扫描量限制为下一轮给定s2的额外长度。

但是,IMO,最好编写一个不需要任何重新扫描的函数,而不是这个技巧

char *
xstrcat(char *s1,const char *s2)
{

    for (;  *s1 != 0;  ++s1);

    for (;  *s2 != 0;  ++s1, ++s2)
        *s1 = *s2;
    *s1 = 0;

    return s1;
}

void
func(char *s1,const char *s2,const char *s3,const char *s4)
{

    s1 = xstrcat(s1,s2);
    s1 = xstrcat(s1,s3);
    s1 = xstrcat(s1,s4);
}