如何在C / C ++中处理unicode字符序列?

时间:2010-09-02 03:49:29

标签: c++ c unicode character-encoding ascii

在C和C ++中处理unicode字符序列有哪些更便携,更干净的方法?

此外,如何:

- 读取unicode字符串

- 将unicode字符串转换为ASCII以保存一些字节(如果用户只输入ASCII)

- 打印unicode字符串

我也应该使用这个环境吗?我已经读过关于LC_CTYPE的例子,我应该关心它作为开发人员吗?

4 个答案:

答案 0 :(得分:8)

  

什么是便携和清洁   处理unicode字符的方法   C和C ++中的序列?

让您的计划中的所有字符串都为UTF-8, UTF-16, or UTF-32。如果由于某种原因需要使用非Unicode编码,请对输入和输出进行转换。

  

读取unicode字符串

您读取ASCII文件的方式相同。但是仍然有很多非Unicode数据,因此您需要检查数据是否是 Unicode。如果不是(或当你首选的内部编码是UTF-32时它是UTF-8),你需要转换它。

  • 通过验证可以可靠地检测到UTF-8和UTF-32。
  • 可以通过BOM检测到UTF-16。
  • 如果不是UTF编码,则可能是ISO-8859-1或Windows-1252。
  

将unicode字符串转换为ASCII   保存一些字节(如果只是用户   输入ASCII)

别。如果您的数据都是ASCII,那么UTF-8将占用完全相同的空间。如果不是,转换为ASCII时将丢失信息。如果你关心保存字节。

  • 选择最佳的UTF编码。对于字符U + 0000到U + 007F,UTF-8是最小的。对于字符U + 0800到U + FFFF,UTF-16是最小的。
  • 像gzip一样使用数据压缩。有一个专为Unicode设计的SCSU编码,但我不知道它有多好。
  

打印unicode字符串

编写UTF-8与编写ASCII没有区别。

除了在Windows命令提示符下,因为它仍然使用旧的“OEM”代码页。在那里,你可以使用WriteConsoleW和UTF-16字符串。

  

我也应该使用这个环境吗?   我读过有关LC_CTYPE的例子,   我应该关心它作为开发人员吗?   ?

LC_CTYPE是从每种语言都有自己的字符编码,以及它自己的ctype.h函数的日子开始的延续。今天Unicode Character Database照顾到了这一点。 Unicode的优点在于字符编码处理与区域设置处理分开(立陶宛语,土耳其语和阿塞拜疆语的special uppercase/lowercase rules除外)。

但是每种语言仍然有自己的排序规则和数字格式规则,因此您仍然需要这些语言环境。并且您需要将您的语言环境的字符编码设置为UTF-8。

答案 1 :(得分:3)

  

在C和C ++中处理unicode字符序列有哪些更便携,更干净的方法?

使用像ICU这样的库。如果你做不到,那就是绝对不可能 - 不能自己滚动。准备好了 Hard Time 。另外,请查看有关示例源代码的Unicode.or g文档。

  

我也应该使用这个环境吗?

是。您可能还需要使用std::setlocale函数。这将允许您设置与您想要的编码相对应的区域设置,例如如果您想使用英式英语作为语言而使用UTF-8作为编码,则set LC_CTYPE to en_GB.UTF8

C ++ 03没有为您提供处理Unicode的方法。您最好的选择是使用wchar_t数据类型(以及std::wstring扩展名)。但请注意,不同操作系统的大小和字符编码是不同的。例如。 Windows使用2个字节用于wchar_t和UTF-16编码,而GNU / Linux和Mac OSX使用4个字节和UTF-32。

C ++ 0x应该通过允许Unicode文字codecvt方面,C Unicode TR支持(读取<uchar.h>)等来修改这种情况,但对大多数编译器来说这是一条很长的路要走。 (这里有几个问题,应该可以帮助你开始。)

答案 2 :(得分:0)

如果适合,您需要将Unicode读取,打印或转换为ASCII吗?只需使用UTF-8,所有这些对您来说绝对透明。

  • 阅读,写作没有区别
  • ASCII已经是UTF-8的子集

对于文本分析/处理,使用ICU,Boost.Locale甚至Qt,Glib等优秀的库,它们可以提供非常好的文本分析/处理工具。

答案 3 :(得分:0)

在此之前有很好的答案,但没有一个人提到我认为可能存在的问题,因为这个问题也有C标签。我的C知识已经过时,如果我错了,请纠正我。

请注意,大概是零终止的字符串,传统的C字符串函数和UTF-16编码的数据流可能是一个棘手的组合,因为在UTF-16中,许多西方字母数字字符将被编码为两个字节,其他字节全部为零并且因此,以char s系列读取字符数据与单字节字符集不同。