我有一个问题。我正在为Linux编写一款使用波兰语(当然包括波兰字符)的应用程序,编译时收到80个警告,这些只是“警告:多字符字符常量”和“警告:情况标签值超过类型的最大值”。我正在使用std :: string。
我该如何替换std :: string类?
请帮忙。 提前致谢。 问候。
std::string
没有定义特定的编码。因此,您可以在其中存储任何字节序列。但需要注意以下细节:
.c_str()
将返回一个以null结尾的缓冲区。如果您的字符集允许null字节,请不要将此字符串传递给不带长度参数的const char*
参数的函数,否则您的数据将被截断。char
并不表示一个字符,而是一个字节。在计算机历史上,这是我认为最棘手的术语。请注意,根据UTF-16规范化,wchar_t
也不一定保存完整的字符。.size()
和.length()
将返回字节数,而不是字符数。[编辑]关于case
标签的警告与问题(2)有关。您正在使用类型为char
的多字节字符的switch
语句,该类型不能保存多个字节。[/编辑]
因此,只要遵守这三条规则,您就可以在应用程序中使用std::string
。这涉及到STL,包括std::find()
,这些都是由此引起的。由于规范化形式的原因,您需要使用一些更聪明的字符串匹配算法来正确支持Unicode。
但是,在任何使用非ASCII字符的语言编写应用程序时(如果您很谨慎,请将其视为[0,128)
之外的任何内容),您需要了解不同文本数据源中的编码。
这两个问题都没有被任何特定的字符串类解决。您只需要将所有外部来源转换为内部编码。我建议始终使用UTF-8,但在Linux上尤其如此,因为它具有本地支持。我强烈建议将您的字符串字面量放在消息文件中,以忘记问题(1)并仅处理问题(2)。
我不建议在Linux上使用std::wstring
,因为100%的本机API使用带有const char*
函数签名,并且对UTF-8提供了直接支持。如果您使用任何基于wchar_t
的字符串类,您将不断需要转换为/从std::wstring
,最终可能出错,并使所有事情变慢。const wchar_t*
签名。此类功能的ANSI版本执行与const wchar_t*
之间的内部转换。char
的UTF-8,在Windows上使用带有wchar_t
的UTF-16。我记得在Python参考实现中读到过这个诀窍,但是文章很旧了。我不确定现在是否仍然如此。在Linux上,您应该使用您所使用的框架提供的多字节字符串类。
我建议使用glibmm框架中的Glib::ustring,它将字符串存储在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
。
std::wstring
,但我不太确定为什么。 - rhinostd::string
没有定义特定的字符集,但在将多字节字符串存储在其中时需要注意一些边缘情况。请参见我对 jikv
答案的评论。 - André Caron
char
和wchar_t
在多字节字符集中不能保存字符。http://www.joelonsoftware.com/articles/Unicode.html - André Caron