6

C++ でコンソールにフランス語の文字を書き込めません。std::ifstream文字列は、 を使用してファイルからロードされ、 を使用std::getlineしてコンソールに出力されstd::coutます。ファイル内の文字列は次のとおりです。

La chaîne qui は、au コード "TEST_CODE" n'a pas été trouvée à l'aide ロケール "fr" に対応しています。

そして、これが文字列がどのように印刷されているかです:

La cha¯ne qui 対応する au コード "TEST_CODE" n'a pas ÚtÚ trouvÚe Ó l'aide ロケール "fr".

この問題を解決するにはどうすればよいですか?

4

2 に答える 2

5

問題は、コンソールがシステムの残りの部分とは異なるコード ページを使用することです。たとえば、通常、南北アメリカと西ヨーロッパ向けにセットアップされた Windows システムは CP1252 を使用しますが、これらの地域のコンソールは CP437 または CP850 を使用します。

使用しているエンコーディングに一致するようにコンソール出力コード ページを設定するか、コンソールの出力コード ページに一致するように文字列を変換することができます。

コンソール出力コードページを設定します。

SetConsoleOutputCP(GetACP()); // GetACP() returns the system codepage.
std::cout << "La chaîne qui correspond au code \"TEST_CODE\" n'a pas été trouvée à l'aide locale \"fr\".";

または、エンコーディング間で変換する多くの方法の 1 つ (これには VS2010 以降が必要です):

#include <codecvt> // for wstring_convert
#include <locale>  // for codecvt_byname
#include <iostream>

int main() {
    typedef std::codecvt_byname<wchar_t,char,std::mbstate_t> codecvt;

    // the following relies on non-standard behavior, codecvt destructors are supposed to be protected and unusable here, but VC++ doesn't complain.
    std::wstring_convert<codecvt> cp1252(new codecvt(".1252"));
    std::wstring_convert<codecvt> cp850(new codecvt(".850"));

    std::cout << cp850.to_bytes(cp1252.from_bytes("...été trouvée à...\n")).c_str();
}

後者の例では、実際に 1252 と 850 の間で変換する必要があると想定しています。実際のターゲット コード ページを把握するには、関数 GetOEMCP() を使用する必要があります。プログラムを実行しているマシンでの GetACP() の結果。

また、このプログラムは、標準で保証されていないことに依存していることにも注意してください。つまり、ロケール間で wchar_t エンコーディングを共有する必要があります。これは、ほとんどのプラットフォームに当てはまります。通常、すべてのロケールで wchar_t に何らかの Unicode エンコーディングが使用されますが、すべてではありません。


理想的には、どこでも UTF-8 を使用でき、最近の他のプラットフォームと同様に、次のようにすれば問題なく動作します。

#include <iostream>

int main() {
    std::cout << "La chaîne qui correspond au code \"TEST_CODE\" n'a pas été trouvée à l'aide locale \"fr\".\n";
}

残念ながら、Windows は、UTF-16 を wchar_t エンコーディングとして放棄して 4 バイトの wchar_t を採用するか、標準の要件に違反して標準準拠のプログラムを壊すことなく、この方法で UTF-8 をサポートすることはできません。

于 2012-11-15T03:55:52.123 に答える
3

コンソールに Unicode 文字を書きたい場合は、いくつかの初期化を行う必要があります。

_setmode(_fileno(stdout), _O_U16TEXT);

次に、フランス語の文字が正しく表示されます (Consolasコンソール フォントとして使用してテストしました)。

#include <fcntl.h>
#include <io.h>

#include <iostream>
#include <ostream>
#include <string>

using namespace std;

int main() 
{
    // Prepare console output in Unicode
    _setmode(_fileno(stdout), _O_U16TEXT);


    //
    // Build Unicode UTF-16 string with French characters
    //

    // 0x00EE - LATIN SMALL LETTER I WITH CIRCUMFLEX
    // 0x00E9 - LATIN SMALL LETTER E WITH ACUTE
    // 0x00E0 - LATIN SMALL LETTER A WITH GRAVE

    wstring str(L"La cha");
    str += L'\x00EE';
    str += L"ne qui correspond au code \"TEST_CODE\" ";
    str += L"n'a pas ";
    str += L'\x00E9';
    str += L't';
    str += L'\x00E9';
    str += L" trouv";
    str += L'\x00E9';
    str += L"e ";
    str += L'\x00E0';
    str += L" l'aide locale \"fr\".";


    // Print the string to the console
    wcout << str << endl;  
}

Michael Kaplan による次のブログ投稿を読むことを検討してください。

さらに、ファイルからテキストを読み取る場合、どのエンコーディングが使用されているかを知る必要があります: UTF-8? UTF-16LE? UTF-16BE? 特定のコードページ?次に、特定のエンコーディングから Unicode UTF-16 に変換し、Windows アプリケーション内で UTF-16 を使用できます。コード ページ (または UTF-8) から UTF-16 に変換するには、 MultiByteToWideChar()APIまたはATL 変換ヘルパー クラスCA2Wを使用できます。

于 2012-11-15T08:03:56.417 に答える