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

如何替换 std::string 类?

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

有帮助吗?

解决方案

std::string没有定义特定的编码。因此,您可以存储任何序列 字节 在里面。有一些微妙之处需要注意:

  1. .c_str() 将返回一个以 null 结尾的缓冲区。如果您的字符集允许空字节,请不要将此字符串传递给采用空字节的函数 const char* 参数不带长度,否则您的数据将被截断。
  2. A char 不代表一个字符,而是一个**字节. 。恕我直言,这是计算历史上最有问题的术语。注意 wchar_t 也不一定包含完整字符,具体取决于 UTF-16 规范化。
  3. .size().length() 将返回数量 字节, ,而不是字符数。

[编辑] 有关警告 case 标签与问题(2)相关。您正在使用一个 switch 使用 type 的多字节字符语句 char 它不能容纳超过一个字节。[/编辑]

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

然而,当使用任何使用非 ASCII 字符的语言编写应用程序时(如果您偏执,请考虑这之外的任何事情) [0, 128)),您需要了解不同文本数据源中的编码。

  1. 源文件 可能未指定编码,并且可能会使用编译器选项进行更改。任何字符串文字都将遵守此规则。我想这就是您收到警告的原因。
  2. 您将从外部源(文件、用户输入等)获得各种字符编码。当该源指定编码时,或者您可以从某些外部源(即,询问导入数据的用户),那么这就更容易了。除非另有说明,许多(较新的)互联网协议都强制使用 ASCII 或 UTF-8。

任何特定的字符串类都没有解决这两个问题。您只需将所有外部源转换为内部编码即可。我一直建议使用 UTF-8,尤其是在 Linux 上,因为它有原生支持。我强烈建议将字符串文字放在消息文件中,以忘记问题 (1),只处理问题 (2)。

我不建议使用 std::wstring 在 Linux 上,因为 100% 的本机 API 使用函数签名 const char* 并有 直接的 支持 UTF-8。如果您使用任何基于 wchar_t, ,您需要转换为/从 std::wstring 不停地工作,最终会出问题,而且会让一切变慢(呃)。

如果您正在为 Windows 编写应用程序,我建议完全相反,因为所有本机 API 都使用 const wchar_t* 签名。此类函数的 ANSI 版本执行与 const wchar_t*.

一些“可移植”库/语言根据平台使用不同的表示形式。他们使用 UTF-8 char 在 Linux 和 UTF-16 上 wchar_t 在 Windows 上。我记得在 Python 参考实现中读过这个技巧,但这篇文章相当旧了。我不确定这是否是真的。

其他提示

在Linux,则应该使用通过使用一个框架提供多字节字符串类。

我建议油嘴:: ustring,从glibmm框架,以UTF-8编码,其存储字符串。 如果源文件是UTF-8,然后在代码使用多字节字符串文字一样简单:

ustring alphabet("aąbcćdeęfghijklłmnńoóprsśtuwyzźż");

但你不能建立在使用char多字节字符的开关/ case语句。我建议使用一系列ifs的。您可以使用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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top