为什么字符串在strcat()之后被改变了?

这是源代码

int main() { char str[]="dance"; char str1[]="hello"; char str2[]="abcd"; strcat(str1,str2); printf("%s",str); } 

输出 – bcd

为什么strstrcat(str1,str2);之后被改变strcat(str1,str2);

str1没有足够的空间来连接字符串str2 。 这会调用未定义的行为 。 你可能得到任何东西。 预期或意外结果。
现在试试这个:

 #include  #include  int main(void) { char str[]="dance"; char str1[10]="hello"; char str2[]="abcd"; strcat(str1,str2); printf("%s\n",str1); printf("%s\n",str); return 0; } 

输出:

 helloabcd dance 

我知道了…

因为我没有给出str1的大小,所以str1str都是一个接一个地存在于内存中

喜欢

 hello \0 dance 

所以当我连接str1str2之后发生的事情……

 a replaces \0 b replaces d c replaces a d replaces n \0 replaces c 

因此str被改变了

这是一个“未定义的行为”

strstr1str2的大小有限,并且它们被放在堆栈中,顺序取决于编译器。 您可能在堆栈中有类似的东西。

['a']['b']['c']['d']['\0']['h']['e']['l']['l']['o']['\0']['d']['a']['n']['c']['e']['\0']

得到它了?

str1的初始大小之后写入时,您将覆盖堆栈,更改堆栈中的所有其他变量。

您将str2连接到str1 ,但str1不足以容纳两个字符串。 有一个缓冲区溢出会破坏堆栈上第三个字符串的内容, str

当你定义

 char str1[] = "hello"; 

你创建一个由六个字符组成的数组,5个用于“hello”加一个空字符来终止字符串。 字符串已经满了,可以这么说。 快速解决方法是指定数组大小:

 char str1[20] = "hello"; 

现在你应该能够使用strcatstr2附加到str1

在实践中,您应该确保缓冲区足够大以容纳整个字符串:

 char buf[20]; if (strlen(str1) + strlen(str2) < 20) { strcpy(buf, str1); strcat(buf, str2); } 

这很乏味。 还有另一种方法可以在没有缓冲区溢出的情况下连接字符串

 char buf[20]; int n; n = snprintf(buf, 20, "%s%s", str1, str2); 

这可能会缩短整个字符串,但不会溢出缓冲区。 返回值n表示如果有足够的空间,将写入多少个字符,因此您可以使用它来检查。