2012-03-18 24 views
10

流行的软件开发人员和公司(Joel Spolsky, Fog Creek software)倾向于编写C或C++代码时使用wchar_t的为Unicode字符存储。关于良好的编码习惯,何时以及如何使用charwchar_t正确使用字符串存储在C和C++

我特别感兴趣的是在编写利用Unicode的软件时符合POSIX

当使用wchar_t的,您可以查找字符的宽字符数组中的每个字符或每个数组元素的基础上:

/* C code fragment */ 
const wchar_t *overlord = L"ov€rlord"; 
if (overlord[2] == L'€') 
    wprintf(L"Character comparison on a per-character basis.\n"); 

你如何比较的Unicode字节(或字符)使用时char

到目前为止,我的首选用C比较型字符的字符串和字符的方式往往是这样的:

/* C code fragment */ 
const char *mail[] = { "ov€[email protected]", "ov€[email protected]" }; 
if (mail[0][2] == mail[1][2] && mail[0][3] == mail[1][3] && mail[0][3] == mail[1][3]) 
    printf("%s\n%zu", *mail, strlen(*mail)); 

为字节相当于Unicode字符的这种方法扫描。 Unicode欧元符号占用3个字节。因此需要比较三个字符数组字节,以确定Unicode字符是否匹配。通常您需要知道要比较的字符或字符串的大小以及它为解决方案工作产生的位数。这看起来根本不是处理Unicode的好方法。 有没有比较char类型的字符串和字符元素的更好方法?

另外,当使用wchar_t时,如何将文件内容扫描到数组?函数fread似乎没有产生有效的结果。

+9

C++中的Unicode:不要使用'wchar_t',使用正确的Unicode库。 – 2012-03-18 10:35:00

+3

'倾向于使用wchar_t进行Unicode字符编码。没有;他们将它用于Unicode字符_storage_,并且存在很大差异。 – 2012-03-18 10:46:25

+0

[std :: wstring VS std :: string]可能的重复(http://stackoverflow.com/questions/402283/stdwstring-vs-stdstring) – 2012-03-18 10:46:51

回答

10

如果你知道你在处理unicode,那么charwchar_t都不合适,因为它们的大小是编译器/平台定义的。例如,wchar_t在Windows(MSVC)上为2个字节,而在Linux(GCC)上为4个字节。 C11和C++ 11标准已经更加严格一些,并且定义了两个新的字符类型(char16_tchar32_t),并带有用于创建UTF- {8,16,32}字符串的相关字面前缀。

如果您需要存储和操作unicode字符,则应该使用专为该作业设计的库,因为C11之前的版本和pre-C++ 11语言标准都不是用unicode编写的。有一个few to choose from,但ICU是相当流行(并支持C,C++和Java)。

+3

即使C++ 11在unicode上也很轻松。除了强制要求utf8/16/32之间的几种类型和标准转换之外,您不会发现任何类似于排序规则,比较,归一化等等。 – 2012-03-18 11:06:39

+0

就像一个补充,我认为C11在这里试图与C++ 1同步,引入了相同的新的'char ?? _ t'类型。 – 2012-03-18 11:18:04

+0

是的,C11与这些类型/文字的C++ 11同步。 – 2012-03-18 11:22:24

0

我写软件 ,充分利用Unicode时我在POSIX遵守特别感兴趣。

在这种情况下,您可能希望使用UTF-8(与char)作为首选的Unicode字符串类型。POSIX没有很多与wchar_t —一起工作的功能,这主要是Windows的事情。

此方法扫描字节相当于一个Unicode字符。 Unicode欧元符号€ 占用3个字节。因此,需要比较 三个字符数组字节,以确定Unicode字符是否匹配。通常您需要知道要比较的字符或字符串的大小,以及它为解决方案工作产生的位数。

不,你不知道。你只是比较字节。如果字节匹配,字符串匹配。与其他编码一样,strcmp与UTF-8一样合适。

除非您想要类似于不区分大小写或不区分重音的比较,在这种情况下您需要一个适当的Unicode库。

0

你永远不应该比较字节,甚至代码点来判断字符串是否相等。这是因为从用户角度来看,很多字符串可能是相同的,而不是从代码点的角度来看是相同的。