为strncpy创建包装以插入终止null

为strncpy创建包装以插入终止null,c,wrapper,strncpy,C,Wrapper,Strncpy,我决定为strncpy做一个包装器,因为我的源代码需要我做大量的字符串复制。我想确保,如果源等于或大于目标,字符串将终止 这段代码将在生产中使用,所以我只想看看使用这个包装器是否有任何潜在的危险 我从来没有做过包装,所以我正在努力使它完美 非常感谢你的建议 /* Null terminate a string after coping */ char* strncpy_wrapper(char *dest, const char* source, c

我决定为strncpy做一个包装器,因为我的源代码需要我做大量的字符串复制。我想确保,如果源等于或大于目标,字符串将终止

这段代码将在生产中使用,所以我只想看看使用这个包装器是否有任何潜在的危险

我从来没有做过包装,所以我正在努力使它完美

非常感谢你的建议

/* Null terminate a string after coping */
char* strncpy_wrapper(char *dest, const char* source, 
                      const size_t dest_size, const size_t source_size)
{
    strncpy(dest, source, dest_size);
    /* 
     * Compare the different length, if source is greater
     * or equal to the destination terminate with a null.
     */
    if(source_size >= dest_size)
    {
        dest[dest_size - 1] = '\0';
    }

    return dest;
}
===编辑更新===

/* Null terminate a string after coping */
char* strncpy_wrapper(char *dest, const char* source, 
                      const size_t dest_size)
{
    strncpy(dest, source, dest_size);
    /* 
     * If the destination is greater than zero terminate with a null.
     */
    if(dest_size > 0)
    {
        dest[dest_size - 1] = '\0';
    }
    else
    {
        dest[0] = '\0'; /* Return empty string if the destination is zero length */
    }

    return dest;
}

您不需要检查源是否大于目标,只要始终将目标中的最后一个字符设置为“\0”

您不需要检查源是否大于目标,只要始终将目标中的最后一个字符设置为“\0”

在访问阵列之前检查dest_大小,否则您会遇到麻烦:

if (dest_size > 0) {
    dest[dest_size - 1] = '\0';
}

事实上,现在我想起来了,死可能更好:

if (dest_size == 0) {
    fputs(stderr, "strncpy(x,y,0)");
    exit(1);
}
否则,您将遇到与原始strncpy()相同的问题,即如果dest_大小为0,则dest可能不会终止。

在访问阵列之前检查dest_大小,否则您将遇到麻烦:

if (dest_size > 0) {
    dest[dest_size - 1] = '\0';
}

事实上,现在我想起来了,死可能更好:

if (dest_size == 0) {
    fputs(stderr, "strncpy(x,y,0)");
    exit(1);
}

否则,您将遇到与原始strncpy()相同的问题,即如果dest_大小为0,则dest可能不会终止。

如果您对缓冲区的分配没有任何限制,
strndup
可能更合适


它最多将分配和复制
len
字符,并始终以NULL终止。

如果您对缓冲区的分配没有任何限制,则strndup可能更合适


如果dest\u size是要复制的字符数,source\u size是源字符串中的字符数,则它将分配和复制最多
len
个字符,并始终以NULL结尾。

你应该试试这个:


 size_t numchars = dest_size > source_size ? source_size : dest_size;
 strncpy(dest,source,numchars) ;
 dest[numchars] = 0 ;

如果dest_size是要复制的字符数,source_size是源字符串中的字符数。
你应该试试这个:


 size_t numchars = dest_size > source_size ? source_size : dest_size;
 strncpy(dest,source,numchars) ;
 dest[numchars] = 0 ;

您应该研究半标准BSD函数
strlcpy()
strlcat()


您应该考虑ISO Tr24731函数如<代码> STRNCYPYSH(/)代码>在您需要的时候是适当的和可用的。

< P>您应该研究半标准BSD函数<代码> STRCYPY()/<代码>和<代码> STRLCATE()/<代码> < /P>

您应该考虑ISO Tr24731函数如<代码> StncPyPySH(/Cord>)是否适合您需要的地方。

StncPy*()将不会自行终止DEST。0字符将始终来自源代码。这意味着您的示例将无法按照OP的意图工作。strncpy()本身不会0-terminate dest。0字符将始终来自源代码。这意味着你的例子将不会像OP计划的那样工作。我刚刚用更新的源代码编辑了我的问题。我已经提出了一个假设。如果dest大于0。始终终止最后一个元素。否则,在第一个[0]元素中插入null,并返回空的目标字符串。这听起来像什么?如果dest的大小为零,则无法在dest中存储“\0”。不允许访问,因为您只能访问零个字符,但存储“\0”意味着您正在访问一个字符。我不认为死亡是个问题,它就像零误差除法。调用dest_size==0的函数毫无意义。尽早失败是个好主意,这样您至少知道自己在哪里出了问题(在调用strncpy()时)。想象一下除法操作无声地失败了,结果给了您一些随机垃圾;很难调试。我刚刚用更新的源代码编辑了我的问题。我已经提出了一个假设。如果dest大于0。始终终止最后一个元素。否则,在第一个[0]元素中插入null,并返回空的目标字符串。这听起来像什么?如果dest的大小为零,则无法在dest中存储“\0”。不允许访问,因为您只能访问零个字符,但存储“\0”意味着您正在访问一个字符。我不认为死亡是个问题,它就像零误差除法。调用dest_size==0的函数毫无意义。尽早失败是个好主意,这样您至少知道自己在哪里出了问题(在调用strncpy()时)。想象一下除法操作无声地失败了,结果给了您一些随机垃圾;很难调试。