WChars、编码、标准和便携性

WChars、编码、标准和便携性

下面的问题可能不符合要求,如果超出范围,请随时告诉我离开。这里的问题基本上是,“我是否正确地理解了C标准,这是正确的方法吗?”

我想要求澄清、确认和更正我对C中字符处理的理解(因此C+和C+0x)。首先,一个重要的观察:

可移植性和序列化是正交概念。

便携的东西就像C,unsigned intwchar_t..可序列化的东西是这样的uint32_t或者UTF-8。“可移植”意味着您可以在每个受支持的平台上重新编译相同的源代码并获得工作结果,但是二进制表示可能完全不同(甚至不存在,例如tcp对载体鸽子)。另一方面,可序列化的事物总是具有表示,例如,我可以在Windows桌面、手机或牙刷上读取的PNG文件。可移植的东西是内部的,可串行化的东西处理I/O,便携的东西是类型化的,可序列化的东西需要类型双关语。</序言>

谈到C中的字符处理,有两组内容分别与可移植性和序列化相关:

  • wchar_tsetlocale()mbsrtowcs()/wcsrtombs()C标准对“编码”只字不提。事实上,它对任何文本或编码属性都是完全不可知的。上面只写着“你的切入点是main(int, char**);你得到了一个类型wchar_t它可以保存系统的所有字符;您可以获得读取输入字符序列的函数,并将它们转换为可行的wstring,反之亦然。

  • iconv()和UTF-8,16,32:在定义明确的固定编码之间转换代码的函数/库。ICov处理的所有编码都是普遍理解和商定的,只有一个例外。

C的可移植的、编码不可知的世界与它之间的桥梁wchar_t可移植字符类型和确定性外部世界是WCHAR-T和UTF之间的ICUV转换.

因此,我应该始终将字符串存储在与编码无关的wstring中吗?wcsrtombs(),并使用iconv()为了序列化?概念上:


                        my program

    <-- wcstombs ---  /==============\   --- iconv(UTF8, WCHAR_T) -->

CRT                   |   wchar_t[]  |                                <Disk>

    --- mbstowcs -->  \==============/   <-- iconv(WCHAR_T, UTF8) ---

                            |

                            +-- iconv(WCHAR_T, UCS-4) --+

                                                        |

       ... <--- (adv. Unicode malarkey) ----- libicu ---+

实际上,这意味着我会为我的程序入口点编写两个锅炉板包装器,例如C+:


// Portable wmain()-wrapper

#include <clocale>

#include <cwchar>

#include <string>

#include <vector>

这是使用纯标准C/C+编写一个惯用的、可移植的、通用的、与编码无关的程序核心的正确方法吗?(请注意,Unicode规范化或diacritic替换等问题超出了范围;只有在您决定实际需要之后才能解决。Unicode(与你可能想要的任何其他编码系统不同),现在是处理这些细节的时候了吗,例如使用像libicu这样的专用库。)


白衣非少年
浏览 359回答 3
3回答

森林海

我会避开wchar_t输入是因为它依赖于平台(根据您的定义不是“可序列化的”):在Windows上输入utf-16,在大多数类Unix系统上输入UTF-32。相反,使用char16_t和/或char32_t类型来自C+0x/c1x。(如果您没有新的编译器,请将它们设为uint16_t和uint32_t)做定义在UTF-8、UTF-16和UTF-32函数之间转换的函数.别写入重载窄/宽版本的每一,每个字符串函数,就像WindowsAPI对-A和-W所做的那样。采摘一首选内部使用的编码,并坚持使用。对于需要不同编码的事物,根据需要进行转换。

拉风的咖菲猫

与.有关的问题wchar_t编码无关的文本处理太困难了,应该避免。如果像您所说的那样坚持使用“纯C”,则可以使用所有w*像这样的功能wcscat朋友们,但是如果你想做更复杂的事情,你就得跳进深渊。以下是一些困难得多的事情wchar_t如果你只选择一个UTF编码的话:解析Javascript:标识符可以包含BMP之外的某些字符(假设您关心这种正确性)。HTML:你怎么转&#65536;变成一串wchar_t?文本编辑器:如何在wchar_t弦乐?如果我知道字符串的编码,我可以直接检查字符。如果我不知道编码,我必须希望,无论我想对字符串做什么,都是由某个库函数实现的。所以wchar_t有点不相干,因为我不认为这是有用数据类型。您的程序要求可能不同,而且wchar_t可能对你没问题。
打开App,查看更多内容
随时随地看视频慕课网APP