c++ - Strncpy 只能与固定长度数组一起使用

标签 c++ c strcpy strncpy

根据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/

相关文章:

c++ - Opengl 纹理有时会在窗口调整大小时闪烁/移动

c++ - 文件读取 : feof() for binary files

c++ - 编译错误是因为缺少const吗?

c - 为什么在 C 中使用指针?

c - 如何在 C 中为嵌入式系统定义堆栈地址范围

C++ 将 std::string 复制到没有空终止的 char 数组

c++ - child 没有在 fork 中正确终止

c++ - 如何在不混淆字段的情况下声明复数?

c++ - memcpy CString 到 char*

c++ - 如何将指数形式的浮点值转换为点表示法?