根据this StackOverflow 注释 strncpy
切勿与非固定长度数组一起使用。
strncpy
should never be used unless you're working with fixed-width, not-necessarily-terminated string fields in structures/binary files. – R.. Jan 11 '12 at 16:22
我知道如果您为字符串动态分配内存,这是多余的,但是是否有理由使用 strncpy
而不是 strcpy
最佳答案
strncpy
将复制数据直至达到您指定的限制,但如果在字符串末尾之前达到该限制,则目标将未终止。
换句话说,strncpy
有两种可能性。一是你得到的行为与 strcpy
无论如何都会产生的行为完全相同(除了速度较慢,因为它用 NUL 填充目标缓冲区的剩余部分,而你实际上从未真正想要或关心它)。另一个是它产生的结果通常无法用于任何实际用途。
如果要将最大长度的字符串复制到固定长度缓冲区中,可以(例如)使用 sprintf
来完成这项工作:
char buffer[256];
sprintf(buffer, "%255s", source);
与 strncpy
不同,此始终以零结尾结果,因此结果始终可用作字符串。
如果您不想使用 sprintf
(或类似的),我建议您只编写一个实际执行您想要的操作的函数,按照以下一般顺序进行操作:
void copy_string(char const *dest, char const *source, size_t max_len) {
size_t i;
for (i=0; i<max_len-1 && source[i]; i++)
dest[i] = source[i];
dest[i] = '\0';
}
既然您已将其标记为 C++(除了 C):我的建议是通常通过仅使用 std::string
来避免 C++ 中的整个困惑>.
如果您确实必须在 C++ 中使用 NUL 终止序列,您可能会考虑另一种可能性:
template <size_t N>
void copy_string(char const (&dest)[N], char const *source) {
size_t i;
for (i=0; i<N-1 && source[i]; i++)
dest[i] = source[i];
dest[i] = '\0';
}
这仅在目标是实际数组(而不是指针)时才有效,但在这种情况下,它会让编译器推断出数组的大小,而不是要求用户显式传递它。这通常会使代码更快一点(函数调用的开销更少)并且更难搞砸并传递错误的大小。
关于c++ - Strncpy 只能与固定长度数组一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37739439/