我有个问题。我正在为 Linux 编写一个波兰语应用程序(当然还有波兰语字符),编译时收到 80 条警告。这些只是“警告:多字符字符常量”和“警告:案例标签值超过类型的最大值”。我正在使用 std::string。
如何替换 std::string 类?
请帮忙。提前致谢。问候。
std::string
没有定义特定的编码。因此,您可以在其中存储任何字节序列。有一些微妙之处需要注意:
.c_str()
将返回一个以 null 结尾的缓冲区。如果您的字符集允许空字节,请不要将此字符串传递给采用const char*
没有长度的参数的函数,否则您的数据将被截断。char
不代表一个字符,而是一个 **byte。恕我直言,这是计算历史上最成问题的命名法。请注意,这wchar_t
也必然包含一个完整的字符,具体取决于 UTF-16 规范化。.size()
并将.length()
返回字节数,而不是字符数。[编辑]关于标签的警告case
与问题 (2) 有关。您正在使用switch
包含多字节字符的语句,该语句使用的类型char
不能超过一个字节。[/编辑]
因此,您可以在您的应用程序中使用std::string
,前提是您遵守这三个规则。STL 存在一些微妙之处,包括std::find()
由此产生的后果。由于规范化形式,您需要使用一些更聪明的字符串匹配算法来正确支持 Unicode。
但是,在使用任何使用非 ASCII 字符的语言编写应用程序时(如果您是偏执狂,请考虑这一切[0, 128)
),您需要了解不同文本数据源中的编码。
任何特定的字符串类都没有解决这两个问题。您只需要将所有外部源转换为您的内部编码。我一直建议使用 UTF-8,但在 Linux 上尤其如此,因为它具有原生支持。我强烈建议将您的字符串文字放在消息文件中,以忘记问题 (1) 并只处理问题 (2)。
我不建议std::wstring
在 Linux 上使用,因为 100% 的原生 API 使用函数签名const char*
并直接支持 UTF-8。如果您使用任何基于 的字符串类wchar_t
,您将需要不停地转换为/从不std::wstring
停止并最终出错,除了让一切变慢(呃)。
如果您正在为 Windows 编写应用程序,我会建议完全相反,因为所有本机 API 都使用const wchar_t*
签名。此类函数的 ANSI 版本执行与const wchar_t*
.
一些“便携式”库/语言使用基于平台的不同表示。char
他们在 Linux 上使用 UTF-8,wchar_t
在 Windows 上使用 UTF-16。我记得在 Python 参考实现中阅读过那个技巧,但这篇文章已经很老了。我不确定这是否是真的。
在 linux 上,您应该使用您使用的框架提供的多字节字符串类。
我推荐来自 glibmm 框架的 Glib::ustring,它以 UTF-8 编码存储字符串。如果您的源文件是 UTF-8 格式,那么在代码中使用多字节字符串文字就像:
ustring alphabet("aąbcćdeęfghijklłmnńoóprsśtuwyzźż");
但是您不能使用char
. 我建议使用一系列if
s. 您可以使用 Glibmm ,但它的可读性不是很好(您可以使用Wikipedia 中波兰字母表中gunichar
的表格获取字符的正确 unicode 值):
#include <glibmm.h>
#include <iostream>
using namespace std;
int main()
{
Glib::ustring alphabet("aąbcćdeęfghijklłmnńoóprsśtuwyzźż");
int small_polish_vovels_with_diacritics_count = 0;
for ( int i=0; i<alphabet.size(); i++ ) {
switch (alphabet[i]) {
case 0x0105: // ą
case 0x0119: // ę
case 0x00f3: // ó
small_polish_vovels_with_diacritics_count++;
break;
default:
break;
}
}
cout << "There are " << small_polish_vovels_with_diacritics_count
<< " small polish vovels with diacritics in this string.\n";
return 0;
}
您可以使用以下方法编译它:
g++ `pkg-config --cflags --libs glibmm-2.4` progname.cc -o progname
std::string
用于 ASCII 字符串。由于您的波兰字符串不适合,您应该使用std::wstring
.