【问题标题】:What is the advantage of strlmove vs strmove in C?strlmove 与 strmove 在 C 中的优势是什么?
【发布时间】:2008-11-04 05:15:32
【问题描述】:

为了修剪前导空格,我们使用 strmove。但我们被建议使用 strlmove 而不是 strmove。我已经阅读并使用了 strlcpy 和 strlcat。 strlmove 是否有类似的功能,它的优点是什么?

编辑 1:谢谢 Mike B 和 Chris Young。这就是我们使用 strlcpy 的方式。

size_t strlcpy(char *dst, const char *src, size_t size)
{
    strncpy(dst, src, size - 1);
    dst[size - 1] = '\0';
    return(strlen(src));
}

所以我只是想以同样的方式使用 strlmove() 。我想确认是否定义了有关 strlmove() 实现的任何规范。我知道这是我能问的最好的地方之一。

编辑 2:strlmove() 的实现方式与 strlcpy() 和 strlcat() 使用 memmove() 相同。

size_t strlmove(char *dst, const char *src, size_t size)
{
    //Error if the size is 0
    //If src length is greater than size; 
    //   memmove(dst, src, size-1) and dst[size] = \0;
    //Otherwise
    //   memmove(dst, src, length(src));
    return source len;
}

感谢所提供的帮助和支持。

谢谢, 马修·李菊

【问题讨论】:

  • 这是 Google 找到 strlmove() 引用的唯一地方;它更了解 strmove()。

标签: c


【解决方案1】:

strmove、strlmove、strlcpy、strlcat 都是标准 C 函数,所以如果不知道您使用的是哪个特定的非标准库,我无法评论它们的作用。标准C提供strcpy、strcat、strncat、strncpy、memmove、memcpy等。

如果您不知道源字符串是否适合目标缓冲区,则使用 strncpy 而不是 strcpy 是有意义的。然而,strncpy 有一个主要的性能问题,它总是 写入为大小指定的字节数。那就是:

char buf[4096];
strncpy(buf, "Hello", sizeof buf);

将写入'H'、'e'、'l'、'l'、'o'并用'\0'填充buf的剩余4091字节。 strncpy 需要注意的另一件事是,如果 size 参数小于源字符串长度加上它的 null,它不会以 null 终止字符串。例如:

char buf[5];
strncpy(buf, "Hello", sizeof buf);

会将 'H', 'e', 'l', 'l', 'o' 写入 buf 并且不会以 null 结尾。

【讨论】:

    【解决方案2】:

    作为Chris Young mentions,这些例程不是标准的(或者据我所知,在广泛、常用的情况下),所以我不能 100% 确定更多细节,但是:

    通常,str() 例程的strl() 变体采用一个额外的参数来指示目标缓冲区的大小。该例程保证它不会将数据写入缓冲区末尾(因为它知道大小)。通常strl() 函数也会保证它们会在字符串的末尾或缓冲区的末尾放置一个终止空字符(可能会截断在那里创建的任何字符串),这样您也可以保证有一个终止的字符串,它将一般可以传递给其他str()函数。请注意,如果缓冲区的长度被指定为 0(零),该函数将放置一个终止空字符(因为缓冲区中没有任何空间)。

    在我看来,使用strl()(或strn())函数而不是相应的str() 例程来防止缓冲区溢出几乎总是更好。

    【讨论】:

      【解决方案3】:

      快速谷歌搜索显示 strlmove 函数的唯一提及是在 stackoverflow :)。所以它可能不是很常见的功能。
      但是,如果我们假设这个函数本质上与strlcpy 很接近,那么这个函数与strmove 的不同之处在于它使用大小参数移动有限数量的字节并使目标字符串为NULL 终止

      【讨论】:

      • 是的,Ilya 可能是最后一个实施方案。
      【解决方案4】:

      至少在 Theo de Raadt 的版本中,strncpy 和 strlcpy 之间有一个很大的区别,这是您在实现中遗漏的。如果给定字符串的长度小于缓冲区大小,则 strncpy 用空字节填充缓冲区的其余部分。在许多情况下,这可能只是一个很小的区别,但由于许多 c 程序员倾向于使用超大缓冲区来位于安全站点上,因此它可以有所作为。

      
      strncpy(buffer, "bla", 1024);
      

      会将 1021 '\0' 写入缓冲区,尽管一个就足够了。 strlcpy 只写一个 '\0'。

      【讨论】:

      • 哇...很好的发现。我们在实施过程中错过了这一点。我已经纠正了。感谢您发现它。
      【解决方案5】:

      正如克里斯所说,您当前使用的功能是非标准的。 ...更糟糕的是,它们仍然非常低效并且仍然容易出错。您应该能够轻松地创建几个使用 memcpy/memmove 并采用 (char *)s 的 API,它们可以在任何地方工作并且可能比非标准更快。您当前正在使用的变体。

      但是,如果您希望其他人完成繁重的工作,并免费获得安全/可用性,您可以查看 ustr 之类的东西...这意味着易于集成,是标准的。 C、安全、快速,可以处理常量/自动/utf8/动态字符串。还有其他选择。

      【讨论】:

        猜你喜欢
        • 2011-03-25
        • 2011-07-19
        • 2011-02-07
        • 2014-06-03
        • 2016-07-03
        • 1970-01-01
        • 2014-08-03
        • 2015-03-05
        • 1970-01-01
        相关资源
        最近更新 更多