2

プロジェクトでは、すべての内部文字列が utf-8 エンコーディングで保持されます。このプロジェクトは Linux と Windows に移植されています。現在、to_lower 機能が必要です。

POSIX OS では、std::ctype_byname("ru_RU.UTF-8") を使用できます。しかし、g++ (Debian 4.3.4-1) では、ctype::tolower() はロシア語の UTF-8 文字を認識しません (ラテン語のテキストは小文字で問題ありません)。

Windows では、"ru_RU.UTF-8" 引数を指定して std::ctype_byname を構築しようとすると、mingw の標準ライブラリが "std::runtime_error: locale::facet::_S_create_c_locale name not valid" という例外をスローします。

Windows で utf-8 の std::ctype を実装/検索するにはどうすればよいですか? プロジェクトはすでに libiconv に依存しています (codecvt ファセットはそれに基づいています) が、to_lower を実装する明確な方法がわかりません。

4

3 に答える 3

3

STLportを使ってみる

  ここでは、STLport を使用して utf8 ファイルを読み書きする方法について説明します。
utf8 は、ワイド文字をエンコードする方法です。そのため、エンコーディングの管理
C++ 標準ライブラリは、一部である codecvt ロケール ファセットによって処理されます。
ctype カテゴリの。ただし、utf8 はエンコーディングがどのように行われなければならないかを説明するだけです
文字の分類には使えないので情報不足
ロケールの ctype カテゴリ ファセット全体を生成する方法を知る
実例。

C++ では、次のコードが例外をスローすることを意味します。
作成が失敗したことを通知します。

#含む
// std::runtime_error 例外をスローします。
std::locale loc(".utf8");

同じ理由で、に基づいて ctype ファセットを使用してロケールを構築します。
UTF8 も間違っています:

// std::runtime_error 例外をスローします:
std::locale loc(locale::classic(), ".utf8", std::locale::ctype);

utf8 エンコーディングを処理するロケール インスタンスを取得する唯一のソリューション
codecvt ファセットが utf8 に基づく必要があることを明確に通知することです。
エンコーディング:

// 必要なプラットフォーム サポートがあれば成功します。
locale loc(locale::classic(), new codecvt_byname(".utf8"));

  ロケール インスタンスを取得したら、それをファイル ストリームに挿入して
utf8 ファイルの読み取り/書き込み:

std::fstream fstr("file.utf8");
fstr.imbue(loc);

ファセットに直接アクセスして、utf8 エンコード/デコード操作を実行することもできます。

typedef std::codecvt codecvt_t;
const codecvt_t& encoding = use_facet(loc);

ノート:

1. utf8 の前にはドット (「.」) が必須です。これは POSIX 規則、ロケールです
名前の形式は次のとおりです。
言語[_country[.encoding]]

例: 'fr_FR'
    'フランス語'
    「ru_RU.koi8r」

2. utf8 エンコーディングは、現時点では Windows でのみサポートされています。あまり一般的ではない
utf7 エンコーディングもサポートされています。
于 2009-09-01T04:55:31.337 に答える
2

キリル文字の to_lower だけが必要な場合は、自分で関数を作成できます。

АБВГДЕЖ in UTF8 D0 90 D0 91 D0 92 D0 93 D0 94 D0 95 D0 96 0A
UTF8 の абвгдеж D0 B0 D0 B1 D0 B2 D0 B3 D0 B4 D0 B5 D0 B6 0A

ただし、UTF8 はマルチバイト エンコーディングであることを忘れないでください。

また、(libiconv を使用して) 文字列を UTF8 から wchar_t に変換し、Windows 固有の関数を使用して to_lower を実装することもできます。

于 2009-09-02T23:04:53.000 に答える