给定目标编码时如何将 wint_t 转换为 char?
Posted
技术标签:
【中文标题】给定目标编码时如何将 wint_t 转换为 char?【英文标题】:How to convert wint_t to char when given the target encoding? 【发布时间】:2016-02-23 08:35:08 【问题描述】:拥有从getwc(fh)
获得的wint_t
Unicode 代码点。使用 Windows 函数,当我知道目标编码时,如何将其转换为窄 char
?我知道可以使用 8 位编码(比如windows-1250
)来表示字符。
与WideCharToMultiByte()
函数相比,有没有类似的函数可以转换单个宽字符而不是字符串?应该如何正确完成?
这个问题和我的How to process CSV lines with nul char in some elements?有关
【问题讨论】:
这听起来像我在 ncurses 中所做的。它相当简单,因此您可能需要改进您的问题,以关注某些存在障碍的方面。 在 Windows 上,wint_t
和 wchar_t
都不能保存 Unicode 代码 point(这需要 >= 24 位),因为 wchar_t
仅16 位。它们可以保存 UTF-16 代码 units,这是另一回事。超出基本多语言平面的代码点将需要 两个 代码单元(代理对)。
en.cppreference.com/w/cpp/locale/codecvt 但许多编译器/STDlib 实现仍然没有正确和完整的实现
这通常是不可能的。一些 Unicode 代码点转换为两个 char
s。比如在CP936中,所有的汉字都占据了两个char
s。
@DevSolar:你是对的。我已将问题限制在 Windows 及其 UTF-16 表示的特殊情况。我只需要解决用户可以选择导出已处理文件(由 Windows 应用程序生成)或人类语言或 UTF-16 的 8 位编码的情况。
【参考方案1】:
设计上没有等效的功能。你错误地假设它甚至可以逐字母转换。这几乎就像一个字母一个字母地把英语翻译成法语一样不可能——它就是行不通的。
【讨论】:
我添加了我知道目标编码并且它是 8 位编码的假设。拥有一个 Unicode 代码点——即对确切字符的引用——并且知道 8 位编码,单个字符的转换是可能的,或者由于该字符不能在目标编码中表示而失败。哪里错了? @pepr: U+004C U+0327 是两个 Unicode 代码点的序列,在 CP-1250 中转换为char(0xC8)
。
@pepr:MSalters 给出了错误的序列;应该是 U+0043 U+030C。这也是 Č
字符...结合了变音符号和分解形式 FTW。
我确实很糟糕,U+0043 U+0327 是 char(0xC7)
而 U+0043 U+030C 是 char(0xC8)
。
@pepr:wchar_t
的大小对您来说不是问题; CP-1250 的所有字符都在 Unicode BMP 中(iow,适合 16 位)。但是,“由本机 Windows 函数生成”意味着您的代码可能会在 Windows 升级或不同的 Windows 版本时中断。以上是关于给定目标编码时如何将 wint_t 转换为 char?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 3 中将 captureStillImageAsynchronously(sampleBuffer) 转换为 base64 编码