基本上,您正在重新发明 1996 年推出的 strlcpy - 请参阅 Todd C. Miller 和 Theo de Raadt 的 strlcpy and strlcat - consistent, safe, string copy and concatenation 论文。你可能没有听说过它,因为它是 refused to be added to glibc,被 glibc 维护者称为“非常低效的 BSD 垃圾”,即使被所有其他操作系统采用,它也一直战斗到今天 - 请参阅 Damien Miller 的 Secure Portability 论文(部分4:选择正确的 API)。
您可以使用libbsd 项目(打包在 Debian、Ubuntu 和其他发行版上)或通过简单地复制在网络上很容易找到的源代码(例如在此答案中的两个链接上)在 Linux 上使用 strlcpy。
但是回到你的问题,在你的情况下什么是最有效的,在这里你没有使用源字符串长度是我的想法,基于来自 OpenBSD 的 strlcpy 源 http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/string/strlcpy.c?rev=1.11 但没有检查原始字符串的长度,它可能很长,但仍以正确的 '\0' 结尾:
char *d = str; // the destination in your example
const char *s = string; // the source in your example
size_t n = max; // the max length in your example
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL */
if (n == 0) {
if (max != 0)
*d = '\0'; /* NUL-terminate dst */
}
这是http://cantrip.org/strlcpy.c 上使用 memcpy 的 strlcpy 版本:
/*
* ANSI C version of strlcpy
* Based on the NetBSD strlcpy man page.
*
* Nathan Myers <ncm-nospam@cantrip.org>, 2003/06/03
* Placed in the public domain.
*/
#include <stdlib.h> /* for size_t */
size_t
strlcpy(char *dst, const char *src, size_t size)
{
const size_t len = strlen(src);
if (size != 0) {
memcpy(dst, src, (len > size - 1) ? size - 1 : len);
dst[size - 1] = 0;
}
return len;
}
我认为哪个更有效取决于源字符串。对于非常长的源字符串,strlen 可能需要很长时间,如果您不需要知道原始长度,那么第一个示例对您来说可能会更快。
这完全取决于您的数据,因此对真实数据进行分析是找出答案的唯一方法。