C - 在没有 strlcpy 的平台上的 strncpy 方面的 strlcpy



我知道,strlcpy比从源复制到目标字符数组时strncpy更安全,我们希望目标以 null 结尾, 以下包装器可以吗?

size_t strlcpy(char *dst, const char *src, size_t size) {
if (size != 0) {
int maxSize = size - 1;
int currSize = -1;
while ((++currSize < maxSize) && (*dst++ = *src++));
*dst = 0;
return currSize;
}
return 0;
}

请评论。

检查size是否高于零具有误导性,因为size_t是无符号的。更具可读性的检查是if (size != 0) ...

另一个问题是strncpy用零填充其目的地,直到sstrlcpy不会这样做。如果您想匹配strlcpy的行为,请在不可用的系统上编写自己的实现,而不是依赖strncpy

您的实现非常快,但有两个怪癖:

  • 一个怪癖是,当有足够的空间时,您的函数会写入两个 NUL 字符而不是一个。
  • 另一个怪癖是不指示问题的返回值。

除了这些怪癖之外,您的版本在功能上等同于strxcpy()吸引力混乱。但是,您的代码速度快 30-100%,具体取决于我使用的机器。在这方面干得好!

关于返回值,以下是我观察到的差异:

  • 原始strlcpy返回src长度:

    • 缺点: 不安全不必要的慢
    • 优点:strlcpy(d,s,n)相当于snprintf(d,n,"%s",s)
  • Strxcpy by Attractive Chaos 返回写入的字节数:

    • 优点:当 SRC 太长时,返回值不会清楚地指示问题
    • 缺点:返回值偏离 strlcpy
  • 您的函数返回写入的字符串长度的长度:

    • 缺点:
      • 当 SRC 太长时,返回值没有明确指示问题
      • 返回值不指示是否写入了 NUL 字符
    • 优点:更符合原来的STRLCPY。

在我的首选实现中,所有提到的功能缺点都是固定的:

ssize_t safe_strlcpy(char *dst, const char *src, size_t size)
{
if (size == 0)
return -1;
size_t ret = strnlen(src, size);
size_t len = (ret >= size) ? size - 1 : ret;
memcpy(dst, src, len);
dst[len] = '';
return ret;
}

src太长且不完全适合时,它返回size;如果size为零,则返回 -1;否则 - 写入字符串长度。因此,当一切正常时,返回值仍然与strlcpy一致。它基于 Git 对原始 strlcpy 的实现。

相关内容

  • 没有找到相关文章

最新更新