当我想复制src_str
到时我应该使用什么dst_arr
,为什么?
char dst_arr[10];
char *src_str = "hello";
PS:读了很多关于好坏的东西后,我的头比我的电脑磁盘旋转得更快。strncpy
strlcpy
注意:我知道strlcpy
并非随处可用。这不是这里的问题。
strncpy
当您的目标字符串以零结尾时,它永远不是正确答案。strncpy
是一个旨在与非终止的固定宽度字符串一起使用的函数。更准确地说,它的目的是将零终止的字符串转换为非终止的固定宽度字符串(通过复制)。换句话说,strncpy
在这里没有意义。
您在这里真正的选择是 betweenstrlcpy
和 plain strcpy
。
当您想要执行“安全”(即可能被截断)复制到dst_arr
时,要使用的正确函数是strlcpy
.
至于dst_ptr
......没有“复制到dst_ptr
”这样的东西。您可以复制到指向的内存dst_ptr
,但首先您必须确保它指向某处并分配该内存。有很多不同的方法可以做到这一点。
例如,您可以只dst_ptr
指向dst_arr
,在这种情况下,答案与前一种情况相同 - strlcpy
。
或者您可以使用malloc
. 如果您分配的内存量保证足够用于字符串(即至少strlen(src_str) + 1
分配了字节),那么您可以使用普通strcpy
甚至memcpy
复制字符串。在这种情况下没有必要也没有理由使用strlcpy
它,尽管有些人可能更喜欢使用它,因为它以某种方式给了他们额外的安全感。
如果您有意分配更少的内存(即您希望您的字符串被截断),那么strlcpy
就成为正确的函数。
strlcpy()
比strncpy()
你还不如使用它更安全。
没有它的系统通常会有一个s_strncpy()
做同样事情的系统。
注意:你不能复制任何东西,dst_ptr
直到它指向某个东西
我不知道strlcpy。我刚刚在这里发现:
strlcpy() 和 strlcat() 函数分别复制和连接字符串。它们被设计为更安全、更一致且更不易出错的 strncpy(3) 和 strncat(3) 替代品。
所以 strlcpy 接缝更安全。
编辑:这里有完整的讨论。
编辑2:
我意识到我上面写的内容并没有回答您问题的“在您的情况下”部分。如果您了解strncpy 的局限性,我想您可以使用它并围绕它编写好的代码来避免它的陷阱;但如果您不确定自己对它的限制的理解,请使用 strlcpy。
我对 strncpy 和 strlcpy 的局限性的理解是,你可以用 strncpy 做一些非常糟糕的事情(缓冲区溢出),而你可以用 strlcpy 做的最糟糕的事情就是在这个过程中丢失一个字符。
您应该始终使用标准函数,在本例中为 C11strcpy_s()
函数。不strncpy()
,因为不保证零终止是不安全的。而不是 OpenBSD-only strlcpy()
,因为它也是不安全的,而且 OpenBSD 总是提出自己的发明,这些发明通常不会成为任何标准。
请参阅 http://en.cppreference.com/w/c/string/byte/strcpy
函数 strcpy_s 类似于 BSD 函数 strlcpy,除了 strlcpy 截断源字符串以适合目标(这是一个安全风险)
如果您的 C 库没有strcpy_s
,请使用 safec 库。
https://rurban.github.io/safeclib/doc/safec-3.1/df/d8e/strcpy__s_8c.html
首先,您的 dst_ptr 没有分配空间,并且您没有将其设置为指向其他空间,因此分配任何内容可能会导致分段错误。
Strncpy 应该可以正常工作 - 只需执行以下操作:
strncpy(dst_arr, src_str, sizeof(dst_arr));
你知道你不会溢出 dst_arr。如果您使用更大的 src_str,您可能必须在 dst_arr 的末尾放置您自己的空终止符,但在这种情况下,您的源是 < 您的目标,因此无论如何都会用空值填充它。
这在任何地方都有效并且很安全,所以我不会看其他任何东西,除非它的智力好奇心。
另请注意,最好对 10 使用非幻数,这样您就知道它的大小与 strncpy 的大小匹配:)
您不应该为此使用 strncpy 而不是 strlcpy 。更好地使用
*dst_arr=0; strncat(dst_arr,src_arr,(sizeof dst_arr)-1);
或没有初始化
sprintf(dst_arr,"%.*s",(sizeof dst_arr)-1,src_arr);
这里的 dst_arr 必须是数组而不是指针。