strcat & 覆盖

Posted

技术标签:

【中文标题】strcat & 覆盖【英文标题】:strcat & Overwrite 【发布时间】:2022-01-21 23:17:15 【问题描述】:

我在一些网站上阅读了 strcat() C 库函数的documentation。

我也看过这里:Does strcat() overwrite or move the null?

不过,还有一个问题——strcat()函数是否可以用来覆盖destionation字符串中的字符(假设dest字符串有足够的空间存放源字符串,所以不会出错)?

我运行以下代码,发现它没有能力覆盖目标字符串的字符...

char dest[20] = "Hello World";
char src[] = "char";
strcat(dest+1, src);
printf("dest: %s", dest);

假设目标是有一个包含:“Hchar World!”的目标字符串

(我知道 strcat() 也将 NULL 字符('\0')复制到目标字符串,所以如果调用 printf() 函数,它应该打印 Hchar,因为我错误地认为会发生......) .

这可能与 strcat() 相关吗?如果不是,strcpy() 是问题的答案吗?

如果字符串中间有'\0'(NULL字符)的赋值,例如,strcat() 总是会处理第一个'\0'(NULL字符)它满足?我的意思是,如果我有:

 char str[] = "Hello";
 str[2]= 0;
 strcat(str, "ab");

我只是想确定并澄清误解。我很乐意阅读说明。

【问题讨论】:

strcat 将始终附加到现有字符串。 strcpy 也会复制\0,所以你会得到"Hchar" 的结果(实际上是"Hchar\0World" @Bodo 感谢您的回复。你的意思是如果我使用 strcpy() 会得到“Hchar\0World”? 在调试器中尝试,例如onlinegdb.com/Be3_3QfEN在printf行设置断点,查看dest的内容 【参考方案1】:

如 cmets 中所述,strcat 函数将始终(尝试)附加作为其第二个参数(传统上称为 src)给定的字符串作为其第一个参数(@ 987654324@);如果任一字符串不是以空值结尾或目标缓冲区不够大,它将产生未定义的行为。

cppreference site 提供比您链接的网站更好的文档(对于 C 和 C++)。从该网站的strcat 页面:

(1) ... 字符 src[0] 替换了空终止符 dest 结束。生成的字节字符串以 null 结尾。

还有:

注意事项

因为strcat 每次调用都需要寻找dest 的末尾,所以使用strcat 将多个字符串连接成一个是低效的。

因此,在您显示的代码中,调用strcat(dest+1, src); 与调用strcat(dest, src); 具有相同的效果。但是,调用strcpy(dest+1, src); 将产生您想要的结果(打印Hchar)。

【讨论】:

感谢您的回答。这是否意味着 dest 字符串范围内的任何地址都将作为 strcat() 函数中的第一个参数,它总是只处理它在 dest 字符串中识别的第一个 '\0' 的地址,并且源字符串会被连接起来吗? @Modern 是的。它将查找位于您作为第一个参数提供的地址或之后的第一个nul(零)字节,并将第二个参数复制到从该位置开始的内存中。 感谢您的回复。只是为了确保 - 如果在我作为第一个参数写的地址之前有一个空字符,strcat() 将无法识别它,对吗? @Modern 正确。内存/缓冲区中的内容之前作为dest 传递的地址与strcat 函数无关。 感谢您的解释。 strcpy() 是否也正确(你写的关于给定的第一个参数的内容)?【参考方案2】:

strcat 将在dst末尾 写入src 字符串。 如果你想用strcat覆盖dst,你首先需要把dst“end”到你想覆盖它的地方。

看看这个代码示例:

#include <stdio.h>
#include <string.h>

int main()

    char dst[20] = "Hello world";
    char src[] = "char";
    
    dst[1] = '\0';
    strcat(dst, src);
    printf("%s\n", dst);
    return (0);

但是,这不是strcat 的目的,而且正如cmets 中所说,这里使用strcpy 会更合适。

#include <stdio.h>
#include <string.h>

int main()

    char dst[20] = "Hello world";
    char src[] = "char";
    
    strcpy(dst + 1, src);
    printf("%s\n", dst);
    return (0);

【讨论】:

以上是关于strcat & 覆盖的主要内容,如果未能解决你的问题,请参考以下文章

C语言中strcat和strcpy的区别

实现strcat功能

linux strncpy()和strcat使用总结

strcat的几种实现及性能比较

C语言拼接字符串 -- 使用strcat()函数

strcpy strcat strlen实现