我不知道是否有做以下的更清洁,更高效的方式strncpy
考虑max
字符量。 我觉得上午矫枉过正。
int main(void)
{
char *string = "hello world foo!";
int max = 5;
char *str = malloc (max + 1);
if (str == NULL)
return 1;
if (string) {
int len = strlen (string);
if (len > max) {
strncpy (str, string, max);
str[max] = '\0';
} else {
strncpy (str, string, len);
str[len] = '\0';
}
printf("%s\n", str);
}
return 0;
}
我不会用strncpy
在所有的这一点。 至少如果我理解你想要做什么,我可能会做这样的事情:
char *duplicate(char *input, size_t max_len) {
// compute the size of the result -- the lesser of the specified maximum
// and the length of the input string.
size_t len = min(max_len, strlen(input));
// allocate space for the result (including NUL terminator).
char *buffer = malloc(len+1);
if (buffer) {
// if the allocation succeeded, copy the specified number of
// characters to the destination.
memcpy(buffer, input, len);
// and NUL terminate the result.
buffer[len] = '\0';
}
// if we copied the string, return it; otherwise, return the null pointer
// to indicate failure.
return buffer;
}
首先,对于函数strncpy,“没有空字符被隐式地附加到目标的端部,所以目的地将只空终止如果源的C字符串的长度小于NUM”。
我们使用memcpy(),因为函数strncpy()检查每个副本的每个字节为0。 我们已经知道的字符串,memcpy的长度()做它更快。
首先计算该字符串的长度,那么该怎么分配并复制决定
int max = 5; // No more than 5 characters
int len = strlen(string); // Get length of string
int to_allocate = (len > max ? max : len); // If len > max, it'll return max. If len <= max, it'll return len. So the variable will be bounded within 0...max, whichever is smaller
char *str = malloc(to_allocate + 1); // Only allocate as much as we need to
if (!str) { // handle bad allocation here }
memcpy(str,string,to_allocate); // We don't need any if's, just do the copy. memcpy is faster, since we already have done strlen() we don't need strncpy's overhead
str[to_allocate] = 0; // Make sure there's a null terminator
您可以减少由代码量:
int main(void)
{
char *string = "hello world foo!";
int max = 5;
char *str = malloc(max + 1);
if (str == NULL)
return 1;
if (string) {
int len = strlen(string);
if (len > max)
len = max;
strncpy(str, string, len);
str[len] = '\0';
printf("%s\n", str);
}
return 0;
}
没有什么可以做,以加快strncpy()
进一步上升。 你可以通过减少时间:
char string[] = "hello world foo!";
然后避免strlen()
通过使用sizeof(string)
来代替。
请注意,如果最大尺寸较大,要复制的字符串是小的,那么事实是strncpy()
的目标字符串可以很慢下来的东西在每个未使用的位置写入空。
strncpy()
会自动停止,一旦击中NUL; 路过max
不检查就足够了。
我相信这是足够了:
char *str = malloc(max+1);
if(! str)
return 1;
int len = strlen(string);
memset(str, 0, max+1);
int copy = len > max ? max : len;
strncpy(str, string, copy);
基本上你重新发明strlcpy
那是在1996年推出-看是strlcpy和strlcat -一致的,安全的字符串复制和串接 Todd C. Miller拥有和西奥德若特纸。 你可能没有听说过它,因为它是拒绝被添加到glibc的 ,被称为“效率极其低下的BSD废话”,由glibc的维护者,并战斗到所有其他操作系统采用,即使这一天-看安全可移植性纸达米安·米勒(4部分:选择正确的API)。
您可以使用使用是strlcpy在Linux上libbsd项目(打包在Debian,Ubuntu和其他发行版),或通过简单地复制在网络上很容易找到源代码(例如在这个答案的两个链接)。
但要回到上什么是最有效的在你的情况下,如果你不使用这里的源字符串长度的问题是基于我的想法strlcpy
来自OpenBSD源在http://cvsweb.openbsd.org/cgi-箱/ cvsweb / SRC / LIB /的libc /串/ strlcpy.c转= 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 */
}
这里是strlcpy的上一个版本http://cantrip.org/strlcpy.c使用的memcpy:
/*
* 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的可能需要很长时间,如果你不需要知道原来的长度,那么也许第一个例子将是你更快。
这一切都取决于你的数据等实时数据分析将只有这样,才能找出答案。