我们有一组为ASCII字符集开发的应用程序。 现在,我们正试图在冰岛进行安装,并且正在运行到哪里冰岛角色越来越搞砸了问题。
我们通过我们的问题的工作,但我想知道:是否有一个良好的“指南”在那里写C ++,设计用于8位字符,当UTF-8的数据给它,这将正常工作的代码?
我不能指望每个人都读取整个Unicode标准,但如果有更多的东西可以消化的,我想与团队分享,让我们不要再碰到这些问题。
重新编写所有的应用程序使用的wchar_t或其他一些字符串表示是不可行的,在这个时候。 我还会注意到这些应用程序通过网络进行通讯与使用8位字符的服务器和设备,所以即使我们做了统一的内部,我们仍然不得不与在边界处的翻译问题。 在大多数情况下,这些应用只是通过围绕数据; 他们不这样做“过程”比中,从地方到另一个地方复制它的其他任何方式的文本。
所使用的操作系统是Windows和Linux。 我们使用的std :: string和纯老C字符串。 (不要问我任何辩护设计决定。我只是想帮助解决混乱。)
以下是对已经提出了一个清单:
- 绝对最低每一个软件开发人员绝对,积极必须知道的关于Unicode和字符集(没有借口!)
- UTF-8和Unicode的常见问题解答的Unix / Linux
- Unicode指南
这看起来像一个全面快速指南:
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 = 2字节字符
1110 xxxx为三字节字符
1111 0XXX =四字节字符
等等
冰岛字母表中包含的所有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位用于其他目的,这可能会非常棘手。
您可能要检查出ICU 。 他们可能有可用的功能,这将使使用UTF-8字符串工作更容易。
冰岛使用ISO拉丁语1,所以八位应该够了。 我们需要更多的细节弄清楚发生了什么。
冰岛,像法国,德国和西欧的大多数其他语言,可以使用8位字符集(CP1252在Windows上,ISO 8859-1又名Latin1的对* X)的支持。 这是标准做法的Unicode被发明之前,并且仍然相当普遍。 正如你说你有,你不能重写你的应用程序使用WCHAR约束,而且你不需要。
你不应该感到惊讶的是UTF-8是造成问题; UTF-8编码的非ASCII字符(例如重音拉丁字符,刺,ETH等)作为各两个字节。
可以给出的唯一的一般建议是(理论上)很简单:(1)决定什么样的字符集,你要支持(Unicode的,Latin1的,CP1252,...)在您的系统(2)如果你正在供应在一些其他的方式编码的数据(例如UTF-8),那么它在系统边界转码到你的标准(如CP1252)(3)如果你需要提供一些其他的方式编码的数据,...
您可能需要使用宽字符(wchar_t的替代焦炭和std ::而不是wstring的的std :: string的)。 这并不会自动解决你的问题100%,但是是很好的第一步。
还可以使用字符串函数,它们也支持Unicode(参考文档)。 如果事情操纵宽字符或字符串就大致知道他们是宽。