asprintf 有 wchar_t 版本吗?
Posted
技术标签:
【中文标题】asprintf 有 wchar_t 版本吗?【英文标题】:Is there a wchar_t version for asprintf? 【发布时间】:2011-06-16 02:46:39 【问题描述】:我需要一个 C 函数来返回格式化字符串的最终长度,这样我就可以正确分配目标字符串,而不是自己计算长度。有 snprintf
在无法写入整个字符串时执行此操作,但不幸的是没有宽字符替代它。
swprintf
在出错的情况下返回 -1,而不是所需的长度(为什么不一样的行为?!?)
asprintf
提到的标题似乎也无济于事,因为它仅提供非宽版本。
_vscwprintf
可以在 Windows 上使用,但我需要一个跨平台的标准版本,或者至少是一个 Linux 版本,然后我会 #ifdef 代码。
有什么想法吗?谢谢!
【问题讨论】:
【参考方案1】:嗯,您的期望似乎存在根本缺陷。把这些加起来:
-
Windows 有你想要的
Linux 有一个非广泛的变体(
asprintf
没有任何标准,而纯粹是 Linux 和 *BSD 的 GNU 扩展)。
POSIX 将所有与字符串/文件相关的内容定义为以空结尾的 char*
数组,这解释了几乎所有 POSIX 函数都缺乏宽版本。
除了 2、3 和 4 之外,所有现代 Linux 发行版都基于 UTF-8,这意味着非宽版本是“打算使用”的版本。
将这些加起来给出:你为什么需要这样的东西?当然你不是在 Unix 上使用wchar_t
s 你是;)
。如果是,还有两种选择:切换到类似tchar
的解决方案(依赖于平台的 typedef)或完全切换到 UTF-8。
【讨论】:
感谢您的回答。是的,我不得不使用 wchar_t 并且切换到 UTF-8 可能太耗时了。 @gheorghe1800:废弃 wchar_t 并使用 UTF-8。如果您遵循它,就不会出现这个问题。【参考方案2】:是的,swprintf
。请注意,尽管有它的名字,swprintf
是 snprintf
的宽字符等价物,not sprintf
,因为它的第二个参数是缓冲区大小; (幸运的是)没有不占用缓冲区大小的宽字符版本。
此外,由于它在溢出时返回 -1,因此您必须以其他方式获取字符串的总长度。唯一真正可移植的方法是从一定大小的缓冲区开始,尝试格式化并查看它是否足够大,如果没有,则增加大小并重新格式化,直到它足够大。正如您可以想象的那样,这不是很有效。
【讨论】:
谢谢。这是我最初想到的,我只是希望已经实施了更好的解决方案。最后,我想我必须自己计算长度,这在一般情况下似乎容易出错,但我会确保彻底。 有更好的办法;看我的回答。您可能希望回退到 Adam 为 pre-POSIX-2008 系统提供的解决方案。【参考方案3】:POSIX 2008 添加了open_wmemstream
函数,它与vfwprintf
一起满足您的需要。它以前是一个 GNU 扩展,所以它在 GNU 系统上已经存在很长时间了。
这可以很容易地用于构造awprintf
包装器。
【讨论】:
非常感谢。这个 hack 很好,而且确实有效。我仍然不明白为什么像awprintf
这样简单的东西在添加更复杂的功能时无法达到标准。
可能是因为所讨论的标准是 POSIX 并且几乎没有人为 POSIX 系统编码使用wchar_t
,除非他们必须...以上是关于asprintf 有 wchar_t 版本吗?的主要内容,如果未能解决你的问题,请参考以下文章
wchar_t valgrind 问题 - 大小为 8 的读取无效