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