std :: string中的波兰语字符

时间:2010-11-22 14:52:24

标签: c++ linux warnings stdstring polish

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

如何替换std :: string class?

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

3 个答案:

答案 0 :(得分:4)

std::string未定义特定编码。因此,您可以在其中存储 bytes 的任何序列。有一些细微之处需要注意:

  1. .c_str()将返回以null结尾的缓冲区。如果您的字符集允许空字节,请不要将此字符串传递给不带长度的const char*参数的函数,否则您的数据将被截断。
  2. A char不代表字符,而是**字节。恕我直言,这是计算历史中最成问题的术语。请注意,wchar_t也必须包含完整字符,具体取决于UTF-16规范化。
  3. .size().length()将返回 bytes 的数量,而不是字符数。
  4. [edit] 有关case标签的警告与问题(2)有关。您使用的switch语句使用类型char的多字节字符,该字符不能超过一个字节。 [/ edit]

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

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

    1. 可能未指定源文件编码,并且可能会使用编译器选项进行更改。任何字符串文字都将遵守此规则。我想这就是你收到警告的原因。
    2. 您将从外部源(文件,用户输入等)获得各种字符编码。当该源指定编码或您可以从某个外部源获取它(即询问用户导入数据)时,这更容易。除非另有说明,否则许多(较新的)互联网协议都会强制使用ASCII或UTF-8。
    3. 任何特定的字符串类都无法解决这两个问题。您只需将所有外部源转换为内部编码即可。我建议一直使用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