_memccpy 的宽字符版本

Posted

技术标签:

【中文标题】_memccpy 的宽字符版本【英文标题】:Wide-character version of _memccpy 【发布时间】:2020-06-25 02:31:06 【问题描述】:

我必须连接宽 C 风格的字符串,根据我的研究,似乎_memccpy 之类的东西是most ideal(为了避免Shlemiel's problem)。但我似乎找不到宽字符版本。有这样的东西吗?

【问题讨论】:

在您设置和使用相关字符串的位置显示示例代码会改善问题 作为参考,wcscpy() 从 C95 和 VS2019 开始可用。您使用的是什么编译器/版本? @chux 看来wcscpy 没有返回指向复制字符串末尾的指针,这是_memccpy 提供的主要优化。 【参考方案1】:

这样的东西存在吗?

C 标准库不包含 Microsoft 的 _memccpy() 的宽字符版本。它也不包含 _memccpy() 本身,尽管 POSIX 指定了 MS 的 _memccpy() 似乎建模的 memccpy() 函数。

POSIX 还定义了wcpcpy()stpcpy() 的宽版本),它复制一个宽字符串并返回一个指向结果末尾的指针。这不像memccpy() 那样功能齐全,但只要微软的C 库提供它的一个版本,就足以避免Shlemiel 的问题。

但是,您可以使用 swprintf() 连接宽字符串而不会遇到 Shlemiel 的问题,其额外优势是它在标准库中,自 C99 以来。它不提供复制用户指定(宽)字符后停止的memccpy 行为,但它确实返回写入的宽字符数,这相当于返回指向结果末尾的指针。此外,它可以在一次调用中直接连接任意固定数量的字符串。不过,swprintf 确实有很大的开销。

当然,如果swprintf 的开销让您望而却步,那么编写您自己的也很容易。结果可能不如您的库供应商提供的经过良好调整的实现那么有效,但我们正在讨论扩展问题,因此您主要需要在渐近复杂性方面取胜。简单例子:

/*
 * Copies at most 'count' wide characters from 'src' to 'dest', stopping after
 * copying a wide character with value 0 if that happens first. If no 0 is
 * encountered in the first 'count' wide characters of 'src' then the result
 * will be unterminated.
 * Returns 'dest' + n, where n is the number of non-zero wide characters copied to 'dest'.
 */
wchar_t *wcpncpy(wchar_t *dest, const wchar_t *src, size_t count) 
    for (wchar_t *bound = dest + count; dest < bound; ) 
        if ((*dest++ = *src++) == 0) return dest - 1;
    
    return dest;

【讨论】:

以上是关于_memccpy 的宽字符版本的主要内容,如果未能解决你的问题,请参考以下文章

如何在 windows 和 linux 上使用相同的宽字符字符串格式

word count程序,以及困扰人的宽字符与字符

IO库中的宽字符语言

C 中的宽字符输入/输出是不是总是从正确的(系统默认)编码读取/写入?

如何摆脱`打印中的宽字符`?

如何消除 TT 的“打印中的宽字符”警告?