3

「ウムラウト」 (文字 ä、ü、ö、...) と C++ の ifstream に問題があります。

curl を使用して html ページをダウンロードし、ifstream を使用してダウンロードしたファイルを 1 行ずつ読み取り、そこからデータを解析します。これは、次のいずれかのような行になるまでうまくいきます。

te="Olimpija Laibach - Tromsö";
te="Burghausen - Münster";

私のコードはこれらの行を解析し、次のように出力します。

Olimpija Laibach vs. Troms?
Burghausen vs. M?nster

コードから直接ウムラウトを出力するようなことは次のように機能します。

cout << "öäü" << endl; // This works fine

私のコードは次のようになります。

ifstream fin("file");

while(!(fin.eof())) {
    getline(fin, line, '\n');
    int pos = line.find("te=");
    if(pos >= 0) {
         pos = line.find(" - ");
         string team1 = line.substr(4,pos-4);
         string team2 = line.substr(pos+3, line.length()-pos-6);
         cout << team1 << " vs. " << team2 << endl;
   }
}

編集:奇妙なことに、同じコード (唯一の変更点はソースと区切り記号) が別のテキスト入力ファイルに対して機能することです (同じ手順: curl でダウンロードし、ifstream で読み取ります)。次のような行を解析して出力することは問題ありません。

<span id="...">Fernwärme Vienna</span>
4

1 に答える 1

2

に組み込まれているロケールは何finですか? あなたが示すコードでは、それはグローバルロケールであり、リセットしていない場合は"C".

あなたがアングロサクソンの世界の外にいる場合、そしてあなたが示す文字列があなたがそうであることを示唆している場合、あなたが最初に mainすべきことの1つは

std::locale::global( std::locale( "" ) );

これにより、グローバル ロケール (したがって、後で開かれるすべてのストリームのデフォルト ロケール) が、周囲の環境で使用されているロケールに設定されます。(正式には、実装で定義されたネイティブ環境に対してですが、実際には、ユーザーが使用しているものに対してです。)"C"ロケールでは、エンコーディングはほとんどの場合 ASCII です。ASCII はウムラウトを認識せず、標準によれば、入力の不正なエンコーディングは実装定義の文字 (IIRC — このセクションを実際に読み直してからしばらく経ちました) に置き換える必要があります。もちろん、出力には未知の文字があるはずがないため、実装はそれらをチェックせず、通過します。

などは、グローバル ロケールを設定する機会を得る前に開かれるため、具体的std::cinにそれらを吹き込む必要がありますstd::locale( "" )

これが機能しない場合は、使用する特定のロケールを見つける必要がある場合があります。

于 2012-07-23T08:42:24.773 に答える