【问题标题】:Does strncat() always null terminate?strncat() 是否总是 null 终止?
【发布时间】:2017-05-29 20:37:10
【问题描述】:

考虑这段代码:

limit = sizeof(str1)-strlen(str1)-1;
strncat(str1,str2,limit);

如果str2 的长度大于limit,那么strncat Nul 是否终止str1 或者我必须添加此代码,就像strncpy 的情况一样?

str1[sizeof(str1)-1] = '\0'

【问题讨论】:

  • 你确定str1是数组类型的,对吧?
  • 没有错,不完整。您不得不提到str1 是一个数组。
  • str1 是如何声明的?我们可以猜测,但请注意,不熟悉可能出现的问题的人会使用您的代码并......遇到问题。事实上,如果 str1char *,您的代码将失败(可能非常糟糕)。
  • 我编写该代码是为了给出一个通用示例。我假设 str1 是一个数组
  • @SouravGhosh:strncpy 函数会截断字符串,strcpy 函数不会。它们是不同用途的不同功能,用其中一个代替另一个是没有意义的。如果您不想静默截断字符串,但您使用 strncpy 因为它“更安全”,您应该重新评估您的代码安全策略。 strcat_s 函数 旨在成为 strcat 的更安全版本,但普遍的共识是它未能实现这一目标,应该使用组合替代技术(如代码检测)而是。

标签: c arrays string strcat


【解决方案1】:

它总是空终止。

引用C11,第 7.24.3.2 章,(强调我的

strncat 函数附加 不超过 n 个字符(一个空字符和 后面的字符不附加)从s2指向的数组到末尾 s1 指向的字符串。 s2 的初始字符覆盖了空字符 s1 结束。 终止的空字符总是附加到结果中。

还有脚注

因此,s1 指向的数组中可以包含的最大字符数为 strlen(s1)+n+1.

【讨论】:

  • strncat 可能会令人困惑,因为“n”与源字符串相关,而不是与目标缓冲区相关。所以这个函数还是不安全的,可能会导致溢出。大多数其他“n”变体都是为了防止溢出而创建的,这在过去让我感到困惑。
【解决方案2】:

低于 C11 的 C++ 版本不会在 Case 中附加空字符,例如当您的源字符串没有足够的空间用于目标字符串时。

char str[5];
str="Ami"

char str2[10];
str2="NotGoing"

str 有 2 个可用空间,但需要 7 来连接 str2 和 1 用于空字符。 strncat(str,str2,);// 没有空终止的情况。

现在如果 str 没有空间将整个目标 (str2) 连同 str 预先写入的数据一起写入其中,那么在这种情况下,它不会在末尾添加空字符

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 ;

如果满足此条件,您将得到一个空终止的结果,否则您不会。**

【讨论】:

  • C11 是 C 标准,C++ 是 C++。 C++ version lower then C11 部分在语法上是不正确的,任何 C++ 标准版本都不会高于或低于任何 C 标准版本。 C++ documentation on strncat 状态 The resulting byte string is null-terminated.。如果您的实现不这样做,那么您的 strncat 实现就不是标准的。如果您没有将足够的内存传递给指向strncat 的第一个指针,那么您将遇到未定义的行为并越界访问数组并且程序格式错误。
  • 据我所知会有缓冲区溢出,但答案是它不会在末尾添加空字符
  • 如果发生缓冲区溢出未定义的行为,那么strncat 在您的房间中生成demons。在未定义行为的情况下对应该/将会发生什么做出任何假设都是错误的。我认为任何实现可以写一个空终止字符,如果它想在未定义行为的情况下。如果您假设在未定义的行为中会发生某些事情,那么您就不再是在谈论 C 语言了。
  • 我告诉你是因为我在当前的项目中面临这个问题。不能透露代码。
  • 你说得对,Kamil Cuk 是 strncpy 的情况下出现的问题。抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
相关资源
最近更新 更多