C、C++中的字符与字符串(点滴记录)

C/C++ 中的字符类型:

signed char

有符号字符

 

unsigned char

无符号字符

 

char

根据实现,可以是无符号活有符号

 

wchar_t

宽字符

C95

char16_t

UTF-16字符

C++0x, C1x

char32_t

UTF-32字符

C++0x, C1x

wchar_t

刚接触QString时,一直不明白其内部为何为何不采用wchar_t。

Unicode 4.0标准的5.2节提到:

  • "The width of wchar_t is compiler-specific and can be as small as 8 bits. Consequently, programs that need to be portable across any C or C++ compilershould not use wchar_t for storing Unicode text. The wchar_t type is intended forstoring compiler-defined wide characters, which may be Unicode characters in some compilers."

这样看起来,wchar_t 真不是一个好东西。难怪C、C++的新标准中要引入char16_t和char32_t

两种字符集

  • Two sets of characters and their associated collating sequences shall be defined: the set in which source files are written (the source character set), and the set interpreted in the execution environment (the execution character set).

C、C++标准讨论两种字符集:

source input character set

源文件的编码

execution character set

字符串被写入到目标(object)文件时的编码

新标准引入了char16_t和char32_t两种字符类型,但这只解决了第二个编码问题

const char * s1 = u8"hello utf8 string";
const char16_t * s2 = u"hello utf16 string";
const char32_t * s3 = U"hello utf32 string";
const wchar_t * s4 = L"hello wide string"

第一个依然问题依然没能解决:

  • 采用gcc时,可以通过 -finput-charset=gbk 选项告诉编译器源文件的编码(默认utf8?)
  • 采用cl时,源文件有BOM,则按照BOM的编码;如果没有,则使用本地的代码页。

真想知道C、C++为什么不能想python一样,在文件开头可以通过对程序无碍的注释来指定源文件的编码信息。

u8使用一则

在Windows下有这么一个问题:

int main()
{
const char * s = "我是中文";
return 0;
}

如果源文件保存成带BOM的utf8,然后分别用MinGW的gcc 和 MSVC的cl进行编译。这个字符串的execution character set将不同,一个是utf8,一个是gb18030。

如果写成u8"我是中文"将可以解决这个问题。

这样一来,当我们在QString中使用中文的时候,不用再纠结使用

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB18030"));

还是使用

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

更重要的一点是,使用了"u8"我们的Qt程序不需要中文的编解码插件了,即使你的源文件是gb18030编码。

而且,Qt正在考虑是否将utf8而不是现在latin1作为QString的默认转换编码,如果实现的话,我们连 setCodecForCStrings 都不需要了(这对喜欢在源码中喜欢用中文的朋友,应该是一个好消息)。

坏消息是:尽管GCC没有问题,但最新的MSVC2010依然还未支持这种写法。

raw string

这是个不错的东西,至少不用老想着转义字符了:

"C://windows//system32"
R"(C/windows/system32)"

输入和输出

不同于wchar_t,C++0x标准没有提供 u16cout、u32cout 来输出 char16_t 和 char32_t 的字符串。

不过可以先转换成字节流再输出:c16rtomb、c32rtomb (头文件 uchar.h 或 cuchar)

参考

  • http://en.wikipedia.org/wiki/Wide_character

  • http://unicode.org/versions/Unicode4.0.0/ch05.pdf

  • http://labs.qt.nokia.com/2011/03/26/on-utf-8-latin-1-and-charsets/

你可能感兴趣的:(C++,c,String,gcc,qt,character)