为什么字符串在strcat()之后被改变了?
这是源代码
int main() { char str[]="dance"; char str1[]="hello"; char str2[]="abcd"; strcat(str1,str2); printf("%s",str); }
输出 – bcd
为什么str
在strcat(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
的大小,所以str1
和str
都是一个接一个地存在于内存中
喜欢
hello \0 dance
所以当我连接str1
和str2
之后发生的事情……
a replaces \0 b replaces d c replaces a d replaces n \0 replaces c
因此str
被改变了
这是一个“未定义的行为”
str
, str1
, str2
的大小有限,并且它们被放在堆栈中,顺序取决于编译器。 您可能在堆栈中有类似的东西。
['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";
现在你应该能够使用strcat
将str2
附加到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
表示如果有足够的空间,将写入多少个字符,因此您可以使用它来检查。