5

基本的にヨーロッパ諸国の場所の名前であるUTF-8文字列がメモリにいくつかあります(これはより大きなシステムの一部です)。私がやろうとしているのは、それらをテキストファイルに書き込むことです。Linux マシン (Fedora) を使用しています。したがって、これらの名前文字列 (char ポインター) をファイルに書き込むと、ファイルは拡張 ASCII 形式で保存されます。

次に、このファイルを Windows マシンにコピーし、これらの名前を mySQL DB にロードする必要があります。メモ帳 ++ でテキスト ファイルを開くと、エンコーディングがデフォルトで ANSI に設定されます。しかし、UTF-8 へのエンコーディングを選択することができ、次の 3 文字を除いてほとんどすべての文字が期待どおりに見えます: - Ő、ő、および ű。これらは、テキスト内で Ő、ő、および ű として表示されます。

何が間違っているのか考えている人はいますか?これらが拡張 ASCII シンボルの一部ではないことはわかっています。しかし、これをファイルに書き込む方法は次のようなものです。

// create out file stream
std::ofstream fs("sample.txt");

// loop through utf-8 formatted string list
if(fs.is_open()) {
    for(int i = 0; i < num_strs; i++) {
        fs << str_name; // unsigned char pointer representing name in utf-8 format
        fs << "\n";
    }
}
fs.close();

ú、ö、ß などの文字でもすべてがきれいに見えます。問題は上記の 3 文字だけです。これに関する考え/提案/コメントはありますか? ありがとう!

例として、「Gyömrő」のような文字列は「Gyömrű」と表示されます。

4

3 に答える 3

3

予期しない &#​​336 HTML エンティティがどの段階で導入されるかを特定する必要があります。私の最善の推測は、ファイルに書き込んでいる文字列に既に含まれているということです。デバッガーを使用するか、文字列内の & をカウントするテスト コードを追加します。

つまり、あなたの情報源は非 ASCII 文字に厳密には UTF-8 を使用していませんが、時々HTML エンティティを使用しています。これは奇妙ですが、データ ソースが HTML ファイル (またはそのようなもの) の場合に可能です。

また、HEX モードで出力ファイルを確認することもできます。(Notepad++ 用の優れたプラグインがあります) これは、バイト レベルで UTF-8 が実際に何を意味するかを理解するのに役立つことを願っています: 128 個の ASCII シンボルは、値 0 から 127 の 1 バイトを使用します。他のシンボルは 2 ~ 6 バイト (私が思うに) を使用し、最初のバイトは >127 でなければなりません。HTML エンティティは実際にはエンコーディングではなく、'\n' '\r' のようなエスケープ シーケンスです。

于 2012-09-21T22:30:22.520 に答える
1

Notepad++ で開いて UTF-8 を選択すると、文字が適切に表示されない場合、文字は UTF-8 としてエンコードされていません。また、Unicodeエンコーディングとはほとんど関係のない「拡張ASCII」についても言及しています。そして私の考えでは、あなたは実際に文字を何らかのコードページ、たとえば「ISO-8859-1」として書いているのです。

プログラム内のこれらの問題文字列のバイト数を調べてみてください。バイト数が文字数と同じである場合、実際には UTF-8 としてエンコードされていません。

128 文字の ASCII テーブルの外にある文字は、UTF-8 で少なくとも 2 バイトでエンコードされます。

C++ アプリケーション内で Unicode を適切に処理するには、ICU を参照してください: http://site.icu-project.org/

于 2012-09-23T20:24:40.670 に答える
-1

デフォルトでstd::codecvt<char, char, mbstate_t>は何の役にも立たない: これは変換をまったく行わないように定義されている。UTF-8 対応のコード変換ファセットを使用するimbue()必要があります。std::localeとはいえ、実際にcharは Unicode 値を表すことはできません。見ている値は実際にはcharUnicode に適合しますが、すべての値を許可するエンコーディングには適合しませんが、より大きな型が必要になります。

C++ 2011 標準では、UTF-8 変換ファセットが定義されていますstd::codecvt_utf<...>。ただし、内部型には特化されておらず、 、、およびcharのみに特化されています。clang を libc++ と一緒に使用すると、次のようにして正しいことを行うことができます。wchar_tuint16_tuint32_t

#include <fstream>
#include <locale>
#include <codecvt>

int main()
{
    std::wofstream out("utf8.txt");
    std::locale utf8(std::locale(), new std::codecvt_utf8<wchar_t>());
    out.imbue(utf8);
    out << L"\xd6\xf6\xfc\n";
    out << L"Ööü\n";
}

このコードはwchar_tではなく を使用していることに注意してくださいcharchar16_tまたはchar32_t、これらがそれぞれ UCS2 および UCS4 でエンコードされることを意図しているため (標準を正しく理解している場合)、使用するのが合理的に見えるかもしれませんが、それらに対して定義されたストリーム タイプはありません。新しい文字タイプ用にストリーム タイプを設定するのは、やや面倒です。

于 2012-09-21T22:51:25.617 に答える