考虑以下代码:
limit = sizeof(str1)-strlen(str1)-1;
strncat(str1,str2,limit);
如果
str2
的长度大于limit
,strncat
是否会将str1
以Nul结尾,还是我需要像strncpy
一样添加这段代码?str1[sizeof(str1)-1] = '\0'
它总是以空字符结尾。
引用 C11
,第§7.24.3.2章节,(重点强调)
strncat
函数将从由s2
指向的数组中追加不超过n
个字符(不附加空字符及其后面的字符)到由s1
指向的字符串的结尾。s2
的初始字符覆盖了s1
末尾的空字符。最终始终会添加一个空字符。
以及,脚注
因此,指向
s1
的数组中最多可以出现strlen(s1)+n+1
个字符。
C++版本低于C11时,在源字符串没有足够空间的情况下,不会在类似的情况下追加空字符到目标字符串中。
char str[5];
str="Ami"
char str2[10];
str2="NotGoing"
str 只有 2 个空闲位置,但需要 7 个空间来连接 str2,并需要额外的 1 个字符来作为 null 终止符。 在不使用 null 终止符的情况下,使用 strncat(str, str2, )。
如果没有足够的空间将整个目标字符串 (str2) 与预先写入的数据一起写入 str 中,则不会在结尾处添加 null 字符。
char str[10];
str="Ami"
char str2[3];
str2="Hello"
str已经有足够的空间容纳str2,因此在末尾添加一个空字符。
strncat(str,str2,);// case with null termination.
这是我自己制作的正式表格
分配给 str 的长度 >= strlen(str)+ strlen(str2)+1 ;
如果满足此条件,您将获得一个以 null 结尾的结果,否则您将不会。
C++版本低于C11
这部分语法上是不正确的,任何C++标准版本都不会比任何C标准版本高或低。C++ strncat文档指出:结果字节串以空字符结尾。
如果你的实现没有这样做,那么你的strncat
实现就不符合标准。如果你向strncat
的第一个指针传递的内存不足,那么你将遇到未定义的行为,并访问超出数组边界,程序将变得不正常。 - KamilCukstrncat
会在您的房间中生成恶魔。对于未定义行为应该/将会发生什么做任何假设都是错误的。我认为,在未定义行为的情况下,任何实现都可以写入一个空终止字符,如果它想要的话。如果您假设在未定义行为中会发生某些事情,那么您就不再谈论 C 语言了。 - KamilCuk
str1
是数组类型,对吧? - Sourav Ghoshstr1
是一个数组。 - Sourav Ghoshstr1
是如何声明的?我们可以猜测,但要注意,对于不熟悉可能出现的问题的人来说,他们将使用您的代码并且会遇到问题。目前,如果str1
是一个char *
,那么您的代码将失败(可能是惊人的)。 - Jongwarestrncat
并不是strcat
的更安全的版本。 - Dietrich Eppstrncpy
函数截断字符串,而strcpy
函数则不会。它们是具有不同目的的不同函数,使用其中任何一个来替换另一个都没有意义。如果您不想默默地截断字符串,但正在使用strncpy
因为它更“安全”,那么您应该重新评估您的代码安全策略。strcat_s
函数确实被设计为strcat
的更安全版本,但普遍共识是它未能实现这一目标,应该使用组合替代技术(如代码插装)代替。 - Dietrich Epp