我有个问题。 我正在为波兰语编写一个应用程序(当然,还有波兰语字符),编译时会收到80个警告。 这些只是“警告:多字符字符常量”和“警告:案例标签值超过types的最大值”。 我使用std :: string。
我如何replacestd :: string类?
请帮忙。 提前致谢。 问候。
std::string
没有定义一个特定的编码。 您可以在其中存储任何字节序列。 有一些微妙的事情要注意:
.c_str()
将返回一个以空字符结尾的缓冲区。 如果您的字符集允许空字节,请不要将此字符串传递给采用const char*
参数而没有长度的const char*
,否则您的数据将被截断。 char
不代表一个字符,而是一个**字节 。 恕我直言,这是计算历史上最成问题的术语。 请注意,根据UTF-16标准化, wchar_t
也必须保持一个完整的字符。 .size()
和.length()
将返回字节数,而不是字符数。 关于case
标签的警告与问题(2)有关。 您正在使用具有多字节字符的switch
语句,它使用不能包含多个字节的char
类型。 [/编辑]
因此,您可以在您的应用程序中使用std::string
,前提是您遵守这三条规则。 有涉及STL的微妙之处,包括std::find()
,这是后果。 由于规范化形式,您需要使用一些更聪明的字符串匹配算法来正确支持Unicode。
但是,在使用非ASCII字符的任何语言编写应用程序时(如果您偏执,请考虑[0, 128)
以外的任何内容),您需要了解不同文本数据源中的编码。
这两个问题不是由任何特定的字符串类来解决的。 您只需要将所有外部来源转换为您的内部编码。 我一直建议使用UTF-8,但是由于本地支持,尤其如此。 我强烈建议把你的字符串文字放在一个消息文件中来忘记问题(1),只处理问题(2)。
我不建议在Linux上使用std::wstring
,因为100%的本机API使用带有const char*
函数签名,并且直接支持UTF-8。 如果你使用任何基于wchar_t
字符串类,你将需要不断地从std::wstring
转换为/,并最终得到错误的东西,使得一切都变得缓慢(er)。
如果您正在为Windows编写应用程序,我会建议完全相反,因为所有本地API都使用const wchar_t*
签名。 这些函数的ANSI版本执行到const wchar_t*
的内部转换const wchar_t*
。
一些“便携式”库/语言使用基于该平台的不同表示。 他们使用UTF-8在Linux上使用char
,在Windows上使用wchar_t
使用UTF-16。 我记得在Python参考实现中阅读这个技巧,但文章相当老了。 我不确定这是否是真的了。
在linux上,你应该使用由你使用的框架提供的多字节字符串类。
我建议Glib :: ustring,从glibmm框架,它存储UTF-8编码的字符串。 如果源文件是UTF-8,那么在代码中使用多字节字符串文字就像:
ustring alphabet("aąbcćdeęfghijklłmnńoóprsśtuwyzźż");
但是你不能使用char
在多字节字符上建立一个switch / case语句。 我建议使用一系列if
。 你可以使用Glibmm的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
。