4

私は問題があります。Linux 用のポーランド語 (もちろん、ポーランド語の文字を使用) でアプリを作成していますが、コンパイル時に 80 の警告が表示されます。これらは、「警告: 複数文字の文字定数」と「警告: ケース ラベル値が型の最大値を超えています」です。std::string を使用しています。

std::string クラスを置き換えるにはどうすればよいですか?

助けてください。前もって感謝します。よろしく。

4

3 に答える 3

4

std::string特定のエンコーディングを定義しません。したがって、任意のバイトシーケンスを格納できます。注意すべき微妙な点があります。

  1. .c_str()nullで終了するバッファを返します。文字セットでnullバイトが許可されている場合は、長さのないconst char*パラメータを受け取る関数にこの文字列を渡さないでください。渡さないと、データが切り捨てられます。
  2. Acharは文字を表しませんが、**バイトを表します。私見、これはコンピューティングの歴史の中で最も問題のある命名法です。wchar_tUTF-16の正規化に応じて、必ず完全な文字を保持することに注意してください。
  3. .size()文字数ではなく、バイト.length()数を返します。

[編集]caseラベルに関する警告は、問題(2)に関連しています。複数バイトを保持できないswitch型を使用するマルチバイト文字を含むステートメントを使用しています。[/編集]char

したがって、これら3つのルールを尊重すれば、アプリケーションで使用できます。これの結果であるものstd::stringを含めて、STLに関係する微妙な点があります。std::find()正規化形式のため、Unicodeを適切にサポートするには、より巧妙な文字列照合アルゴリズムを使用する必要があります。

ただし、非ASCII文字を使用する言語でアプリケーションを作成する場合(偏執的な場合は、これを外部で検討して[0, 128)ください)、テキストデータのさまざまなソースでのエンコーディングに注意する必要があります。

  1. ソースファイルのエンコーディングが指定されていない可能性があり、コンパイラオプションを使用して変更される可能性があります。文字列リテラルはすべてこのルールの対象になります。これが警告が表示される理由だと思います。
  2. 外部ソース(ファイル、ユーザー入力など)からさまざまな文字エンコードを取得します。そのソースがエンコーディングを指定している場合、または外部ソースからそれを取得できる場合(つまり、データをインポートするユーザーに尋ねる場合)、これは簡単です。多くの(新しい)インターネットプロトコルは、特に指定がない限り、ASCIIまたはUTF-8を課します。

これらの2つの問題は、特定の文字列クラスでは対処されません。すべての外部ソースを内部エンコーディングに変換する必要があります。常にUTF-8をお勧めしますが、ネイティブサポートのためLinuxでは特にそうです。問題(1)を忘れて、問題(2)のみを処理するために、文字列リテラルをメッセージファイルに配置することを強くお勧めします。

Linuxでの使用はお勧めしませんstd::wstring。ネイティブAPIの100%が、UTF-8で関数シグネチャを使用し、UTF-8const char*直接サポートしているためです。に基づく文字列クラスを使用する場合は、すべてを遅くすることに加えて、ノンストップとの間でwchar_t変換を行う必要があり、最終的には問題が発生します。std::wstring

const wchar_t*Windows用のアプリケーションを作成している場合は、すべてのネイティブAPIが署名を使用するため、正反対のことをお勧めします。このような関数のANSIバージョンは、への/からの内部変換を実行しconst wchar_t*ます。

一部の「ポータブル」ライブラリ/言語は、プラットフォームに基づいて異なる表現を使用します。LinuxではUTF-8を使用し、WindowscharではUTF-16を使用wchar_tします。Pythonリファレンス実装でそのトリックを読んだことを思い出しますが、記事はかなり古いものでした。それがもう本当かどうかはわかりません。

于 2010-11-22T20:34:38.327 に答える
1

Linux では、使用するフレームワークによって提供されるマルチバイト文字列クラスを使用する必要があります。

UTF-8 エンコーディングで文字列を格納する glibmm フレームワークの Glib::ustring をお勧めします。ソース ファイルが UTF-8 の場合、コードでマルチバイト文字列リテラルを使用するのは次のように簡単です。

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

ただし、を使用してマルチバイト文字で switch/case ステートメントを作成することはできませんchar。一連のifs を使用することをお勧めします。Glibmm の を使用できますがgunichar、あまり読みやすくありません ( 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
于 2010-11-22T16:03:28.277 に答える
-1

std::stringASCII 文字列用です。ポリッシュ ストリングが収まらないため、 を使用する必要がありますstd::wstring

于 2010-11-22T14:55:47.447 に答える