正确使用C和C++中的字符串存储

Correct use of string storage in C and C++

本文关键字:字符串 存储 C++      更新时间:2023-10-16

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

在编写利用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");

使用char时,如何比较unicode字节(或字符)

到目前为止,我比较字符串和C中char类型的字符的首选方法通常如下所示:

/* C code fragment */
const char *mail[] = { "ov€rlord@masters.lt", "ov€rlord@masters.lt" };
if (mail[0][2] == mail[1][2] && mail[0][3] == mail[1][3] && mail[0][3] == mail[1][3])
    printf("%sn%zu", *mail, strlen(*mail));

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

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

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

如果您需要存储和操作unicode字符,您应该使用专为该作业设计的库,因为C11之前的语言标准和C++11之前的语言规范都没有考虑到unicode。有一些可供选择,但ICU非常受欢迎(并且支持C、C++和Java)。

在编写软件时,我对POSIX合规性特别感兴趣利用Unicode。

在这种情况下,您可能希望使用UTF-8(带有char)作为首选的Unicode字符串类型。POSIX没有太多用于处理wchar_t的功能—这主要是Windows的问题。

此方法扫描与unicode字符等效的字节。这个Unicode欧元符号€占用3个字节。因此需要进行比较三个字符数组字节,以了解Unicode字符是否匹配。经常你需要知道你想要的字符或字符串的大小比较和它为解决方案产生的位。

不,你没有。你只需要比较字节。如果字节匹配,则字符串匹配。strcmp与UTF-8和其他任何编码一样适用。

除非你想要不区分大小写或不区分重音的比较,否则你需要一个合适的Unicode库。

您永远不应该比较字节,甚至代码点来决定字符串是否相等。这是因为从用户的角度来看,许多字符串可以是相同的,而从代码点的角度来看则不相同。