波兰字符在std :: string

我有个问题。 我正在为波兰语编写一个应用程序(当然,还有波兰语字符),编译时会收到80个警告。 这些只是“警告:多字符字符常量”和“警告:案例标签值超过types的最大值”。 我使用std :: string。

我如何replacestd :: string类?

请帮忙。 提前致谢。 问候。

std::string没有定义一个特定的编码。 您可以在其中存储任何字节序列。 有一些微妙的事情要注意:

  1. .c_str()将返回一个以空字符结尾的缓冲区。 如果您的字符集允许空字节,请不要将此字符串传递给采用const char*参数而没有长度的const char* ,否则您的数据将被截断。
  2. char不代表一个字符,而是一个**字节 。 恕我直言,这是计算历史上最成问题的术语。 请注意,根据UTF-16标准化, wchar_t也必须保持一个完整的字符。
  3. .size().length()将返回字节数,而不是字符数。

关于case标签的警告与问题(2)有关。 您正在使用具有多字节字符的switch语句,它使用不能包含多个字节的char类型。 [/编辑]

因此,您可以在您的应用程序中使用std::string ,前提是您遵守这三条规则。 有涉及STL的微妙之处,包括std::find() ,这是后果。 由于规范化形式,您需要使用一些更聪明的字符串匹配算法来正确支持Unicode。

但是,在使用非ASCII字符的任何语言编写应用程序时(如果您偏执,请考虑[0, 128)以外的任何内容),您需要了解不同文本数据源中的编码。

  1. 源文件编码可能没有被指定,并且可能会使用编译器选项进行更改。 任何字符串文字将受制于这个规则。 我想这就是为什么你得到警告。
  2. 您将从外部来源(文件,用户输入等)获得各种字符编码。 当该源指定编码或者可以从某个外部源获取(即询问导入数据的用户)时,则更容易。 除非另有规定,许多(较新的)互联网协议强加ASCII或UTF-8。

这两个问题不是由任何特定的字符串类来解决的。 您只需要将所有外部来源转换为您的内部编码。 我一直建议使用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