复制n,其中函数strncpy字符更有效地用C(Copying n chars with strnc

2019-07-29 05:54发布

我不知道是否有做以下的更清洁,更高效的方式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;
}

Answer 1:

我不会用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;
}


Answer 2:

首先,对于函数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


Answer 3:

您可以减少由代码量:

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()的目标字符串可以很慢下来的东西在每个未使用的位置写入空。



Answer 4:

strncpy()会自动停止,一旦击中NUL; 路过max不检查就足够了。



Answer 5:

我相信这是足够了:

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);


Answer 6:

基本上你重新发明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的可能需要很长时间,如果你不需要知道原来的长度,那么也许第一个例子将是你更快。

这一切都取决于你的数据等实时数据分析将只有这样,才能找出答案。



文章来源: Copying n chars with strncpy more efficiently in C