在我的情况下strncpy或strlcpy

当我想将src_str复制到dst_arr时,我应该使用什么?为什么?

 char dst_arr[10]; char *src_str = "hello"; 

PS:在阅读了很多关于strncpystrlcpy 好坏的事情之后,我的头比我的电脑磁盘旋转得更快。

注意:我知道strlcpy无处不在。 这不是问题所在。

当目标字符串为零终止时, strncpy 永远不是正确的答案。 strncpy是一个用于非终止固定宽度字符串的函数。 更确切地说,其目的是将以零结尾的字符串转换为非终止的固定宽度字符串(通过复制)。 换句话说, strncpy在这里没有意义。

你在这里真正的选择是在strlcpy和plain strcpy之间。

当您想要执行“安全”(即可dst_arr截断)复制到dst_arr ,要使用的正确函数是strlcpy

至于dst_ptr ……没有“复制到dst_ptr ”之类的东西。 您可以复制到dst_ptr指向的dst_ptr ,但首先必须确保它指向某处并分配该内存。 有很多不同的方法可以做到这一点。

例如,你可以让dst_ptr指向dst_arr ,在这种情况下,答案与前一种情况相同 – strlcpy

或者您可以使用malloc分配内存。 如果你保证分配的内存量足够用于字符串(即至少分配了strlen(src_str) + 1个字节),那么你可以使用plain strcpy甚至memcpy来复制字符串。 在这种情况下没有必要也没有理由使用strlcpy ,虽然有些人可能更喜欢使用它,因为它以某种方式给他们带来额外安全感。

如果你故意分配更少的内存(即你希望你的字符串被截断),那么strlcpy将成为正确使用的函数。

strlcpy()strncpy()更安全,所以你也可以使用它。
没有它的系统通常会有一个s_strncpy()来执行相同的操作。

注意 :在指向dst_ptr之前,您无法将任何内容复制到dst_ptr

我不知道strlcpy。 我刚才在这里找到:

strlcpy()和strlcat()函数分别复制和连接字符串。 它们旨在为strncpy(3)和strncat(3)提供更安全,更一致,更少出错的替代品。

所以strlcpy接缝更安全。

编辑 : 此处提供完整的讨论。

编辑2

我意识到我上面写的内容并没有回答你问题的“在你的情况下”部分。 如果您了解 strncpy的局限性,我想您可以使用它并在其周围编写好的代码以避免其陷阱; 但如果您不确定自己对其限制的理解,请使用strlcpy。

我对strncpy和strlcpy的局限性的理解是你可以用strncpy(缓冲区溢出)做一些非常糟糕的事情,而你用strlcpy做的最糟糕的事情就是在这个过程中松掉一个char。

您应始终使用标准函数,在本例中为C11 strcpy_s()函数。 不是strncpy() ,因为这不安全,不能保证零终止。 而不是OpenBSD-only strlcpy() ,因为它也是不安全的,OpenBSD总是提出它自己的发明,它通常不会成为任何标准。

请参见http://en.cppreference.com/w/c/string/byte/strcpy

函数strcpy_s类似于BSD函数strlcpy,除了strlcpy截断源字符串以适应目标(这是一个安全风险)

  • strlcpy不执行strcpy_s执行的所有运行时检查
  • 通过将目标设置为空字符串或在调用失败时调用处理程序,strlcpy不会使故障变得明显。
  • 虽然strcpy_s禁止因潜在的安全风险而截断,但可以使用bounds-checked strncpy_s来截断字符串。

如果您的C库没有strcpy_s ,请使用safec lib。 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的末尾放置你自己的null终止符,但是在这种情况下你的源是<你的dest,所以无论如何它都将用空值填充。

这在任何地方都可以使用并且安全,所以除非它的知识性好奇,否则我不会看其他任何东西。

另请注意,为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必须是一个数组而不是一个指针。