作者:mobiledu2502932307 | 来源:互联网 | 2022-12-07 16:42
所以我读到该strcat
函数将被仔细使用,因为目标字符串应该足够大以容纳其自己和源字符串的内容.我写的以下程序也是如此:
#include
#include
int main(){
char *src, *dest;
printf("Enter Source String : ");
fgets(src, 10, stdin);
printf("Enter destination String : ");
fgets(dest, 20, stdin);
strcat(dest, src);
printf("Concatenated string is %s", dest);
return 0;
}
但对于我在这里写的那个不是这样的:
#include
#include
int main(){
char src[11] = "Hello ABC";
char dest[15] = "Hello DEFGIJK";
strcat(dest, src);
printf("concatenated string %s", dest);
getchar();
return 0;
}
该程序最终添加两者而不考虑目标字符串不够大.为什么会这样?
1> dbush..:
该strcat
函数无法确切知道目标缓冲区的长度,因此它假定传递给它的缓冲区足够大.如果不是,则通过写入缓冲区的末尾来调用未定义的行为.这就是第二段代码中发生的事情.
的代码的第一块也是无效的,因为这两个src
和dest
是未初始化的指针.当您将它们传递给fgets
它时,它会读取它们包含的任何垃圾值,将其视为有效地址,然后尝试将值写入该无效地址.这也是未定义的行为.
使C快速的一个原因是它不会检查以确保您遵守规则.它只是告诉你规则,并假设你遵循它们,如果你没有坏事,可能会或可能不会发生.在你的特殊情况下,它似乎工作,但不能保证.
例如,当我运行你的第二段代码时,它似乎也有效.但如果我改成它:
#include
#include
int main(){
char dest[15] = "Hello DEFGIJK";
strcat(dest, "Hello ABC XXXXXXXXXX");
printf("concatenated string %s", dest);
return 0;
}
程序崩溃了.
2> Steve Summit..:
我认为你的困惑实际上并不是关于它的定义strcat
.您真正的困惑是您认为C编译器会强制执行所有"规则".这个假设是非常错误的.
是的,第一个参数strcat
必须是一个足以存储连接结果的内存指针.在您的两个程序中,都违反了该要求.你可能会从任何一个程序中缺少错误消息得到这样的印象:也许规则不是你想象的那样,strcat
即使第一个参数不是指向足够内存的指针,它也会以某种方式调用.但不是,情况并非如此:strcat
当内存不足时调用肯定是错误的.没有错误消息,或者一个或两个程序似乎"正常"的事实证明没有任何证据.
这是一个类比.(你小时候甚至可能有这种经历.)假设你的母亲告诉你不要跑到街对面,因为你可能会受到汽车的撞击.无论如何,假设你跑到街对面,不要被车撞到.你是否认为你母亲的建议不正确?这是一个有效的结论吗?
总而言之,您所阅读的内容是正确的:strcat
必须谨慎使用.但是,让我们重申一下:你打电话时一定要小心strcat
.如果你不小心,各种各样的事情都可能出错,没有任何警告.事实上,许多风格指南建议不要使用任何功能strcat
,因为如果你不小心,它们很容易被误用.(strcat
只要你小心,这些功能可以完全安全地使用 - 当然并非所有程序员都非常小心.)