我们有一组针对 ASCII 字符集开发的应用程序。现在,我们正尝试在冰岛安装它,但遇到了冰岛字符被搞砸的问题。

我们正在解决我们的问题,但我想知道:是否有一个好的“指南”来编写专为 8 位字符设计的 C++ 代码,并且在提供 UTF-8 数据时可以正常工作?

我不能指望每个人都能阅读整个 Unicode 标准,但如果有更容易理解的内容,我想与团队分享,这样我们就不会再次遇到这些问题。

目前重写所有应用程序以使用 wchar_t 或其他字符串表示形式是不可行的。我还要指出的是,这些应用程序通过网络与使用 8 位字符的服务器和设备进行通信,因此即使我们在内部使用 Unicode,我们仍然会遇到边界翻译问题。大多数情况下,这些应用程序只是传递数据;除了将文本从一个地方复制到另一个地方之外,他们不会以任何方式“处理”文本。

使用的操作系统是Windows和Linux。我们使用 std::string 和普通的 C 字符串。(并且不要要求我为任何设计决策辩护。我只是想帮忙解决这个混乱的问题。)


以下是建议内容的列表:

有帮助吗?

解决方案

这看起来像是一个全面的快速指南:
http://www.cl.cam.ac.uk/~mgk25/unicode.html

其他提示

大多数情况下,只需保持 8 位干净即可。但是,您必须注意任何非 ASCII 字符都会拆分为多个字节,因此如果要换行或截断文本以进行显示,则必须考虑到这一点。

UTF-8 的优点是您始终可以知道多字节字符中的位置:如果位 7 被设置且位 6 复位(字节为 0x80-0xBF),则这是一个尾随字节,而如果位 7 和 6 被设置且位 5 复位(0xC0-0xDF),则它是一个前导字节和一个尾随字节;如果设置了 7、6 和 5 并且重置了 4 (0xE0-0xEF),则它是一个前导字节,带有两个尾随字节,依此类推。设置在最高有效位的连续位数是组成字符的字节总数。那是:

110x xxxx = 两字节字符
1110 xxxx = 三字节字符
1111 0xxx = 四字节字符
ETC

冰岛字母全部包含在 ISO 8859-1 中,因此也包含在 Windows-1252 中。如果这是控制台模式应用程序,请注意控制台使用 IBM 代码页,因此(取决于系统区域设置)它可能会显示为 437、850 或 861. 。Windows 没有对 UTF-8 的本机显示支持;您必须转换为 UTF-16 并使用 Unicode API。

如果它是控制台模式应用程序,则调用 SetConsoleCP 和 SetConsoleOutputCP 并指定代码页 1252 将有助于解决您的问题。不幸的是,选择的控制台字体必须是支持代码页的字体,并且我看不到设置字体的方法。标准位图字体仅支持系统默认的 OEM 代码页。

请注意,完整的 unicode 不适合 16 位字符;因此要么使用 32 位字符,要么使用可变宽度编码(UTF-8 是最流行的)。

UTF-8 的设计正是考虑到您的问题。我要注意的一件事是 ASCII 实际上是一种 7 位编码,因此如果基础设施的任何部分将第 8 位用于其他目的,这可能会很棘手。

您可能想查看 重症监护病房. 。它们可能具有使使用 UTF-8 字符串更容易的函数。

冰岛语使用 ISO Latin 1,因此八位应该足够了。我们需要更多细节来弄清楚发生了什么。

与法语、德语和西欧的大多数其他语言一样,冰岛语可以使用 8 位字符集(Windows 上的 CP1252,*x 上的 ISO 8859-1 又名 Latin1)来支持。这是 Unicode 发明之前的标准方法,并且仍然很常见。正如您所说,您有一个限制,即您无法重写应用程序以使用 wchar,而且您也不需要这样做。

对于 UTF-8 引起的问题,您不应该感到惊讶;UTF-8 对非 ASCII 字符进行编码(例如带重音的拉丁字符、thorn、eth 等)每个为两个字节。

唯一可以给出的一般建议非常简单(理论上):(1)确定您将支持哪个字符集(Unicode,latin1,cp1252,...)(2)如果您以其他方式编码的数据(例如UTF-8),然后将其转码为您的标准(例如CP1252)在系统边界处(3),如果您需要以其他方式提供编码的数据,...

您可能想要使用宽字符(wchar_t 而不是 char,std::wstring 而不是 std::string)。这不会自动解决 100% 的问题,但这是很好的第一步。

还可以使用支持 Unicode 的字符串函数(请参阅文档)。如果某些东西操作宽字符或字符串,它通常会意识到它们是宽的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top