78

こんにちは、 iostreamsを使用してユニコード文字列をコンソールに出力しようとして失敗しました。

私はこれを見つけました: C ++コンソールアプリでユニコードフォントを使用する と、このスニペットが機能します。

SetConsoleOutputCP(CP_UTF8);
wchar_t s[] = L"èéøÞǽлљΣæča";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m);

しかし、iostreams で Unicode を正しく出力する方法が見つかりませんでした。助言がありますか?

これは動作しません:

SetConsoleOutputCP(CP_UTF8);
utf8_locale = locale(old_locale,new boost::program_options::detail::utf8_codecvt_facet());
wcout.imbue(utf8_locale);
wcout << L"¡Hola!" << endl;

編集 このスニペットをストリームでラップする以外の解決策は見つかりませんでした。希望、誰かがより良いアイデアを持っています。

//Unicode output for a Windows console 
ostream &operator-(ostream &stream, const wchar_t *s) 
{ 
    int bufSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
    char *buf = new char[bufSize];
    WideCharToMultiByte(CP_UTF8, 0, s, -1, buf, bufSize, NULL, NULL);
    wprintf(L"%S", buf);
    delete[] buf; 
    return stream; 
} 

ostream &operator-(ostream &stream, const wstring &s) 
{ 
    stream - s.c_str();
    return stream; 
} 
4

15 に答える 15

102

ここでは、Visual Studio 2010 を使用してソリューションを検証しました。このMSDN の記事MSDN のブログ投稿を使用してください。トリックは、へのあいまいな呼び出し_setmode(..., _O_U16TEXT)です。

解決:

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

int wmain(int argc, wchar_t* argv[])
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    std::wcout << L"Testing unicode -- English -- Ελληνικά -- Español." << std::endl;
}

スクリーンショット:

コンソールのユニコード

于 2012-01-29T07:04:16.630 に答える
2

wcout には、CRT とは異なるロケールを設定する必要があります。修正方法は次のとおりです。

int _tmain(int argc, _TCHAR* argv[])
{
    char* locale = setlocale(LC_ALL, "English"); // Get the CRT's current locale.
    std::locale lollocale(locale);
    setlocale(LC_ALL, locale); // Restore the CRT.
    std::wcout.imbue(lollocale); // Now set the std::wcout to have the locale that we got from the CRT.
    std::wcout << L"¡Hola!";
    std::cin.get();
    return 0;
}

テストしたところ、ここに文字列が表示されます。

于 2010-04-01T00:02:33.783 に答える
1
于 2012-07-17T12:40:00.577 に答える
0

最近、Python から Windows コンソールに Unicode をストリーミングしたかったのですが、最低限必要なものは次のとおりです。

  • コンソール フォントを Unicode シンボルをカバーするものに設定する必要があります。幅広い選択肢はありません: コンソールのプロパティ > フォント > Lucida コンソール
  • 現在のコンソール コードページを変更する必要があります。コンソールで実行chcp 65001するか、C++ コードで対応するメソッドを使用します。
  • WriteConsoleW を使用してコンソールに書き込む

Windows コンソールの Java Unicode に関する興味深い記事に目を通してください。

また、Python では、この場合、デフォルトの sys.stdout に書き込むことができません。os.write(1, binarystring) を使用するか、WriteConsoleW のラッパーを直接呼び出す必要があります。C ++でも同じことをする必要があるようです。

于 2010-04-01T08:13:19.360 に答える
0

まず、申し訳ありませんが、おそらく必要なフォントがないため、まだテストできません。

ここで何かが少し怪しいように見えます

// the following is said to be working
SetConsoleOutputCP(CP_UTF8); // output is in UTF8
wchar_t s[] = L"èéøÞǽлљΣæča";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m); // <-- upper case %S in wprintf() is used for MultiByte/utf-8
                   //     lower case %s in wprintf() is used for WideChar
printf("%s", m); // <-- does this work as well? try it to verify my assumption

その間

// the following is said to have problem
SetConsoleOutputCP(CP_UTF8);
utf8_locale = locale(old_locale,
                     new boost::program_options::detail::utf8_codecvt_facet());
wcout.imbue(utf8_locale);
wcout << L"¡Hola!" << endl; // <-- you are passing wide char.
// have you tried passing the multibyte equivalent by converting to utf8 first?
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
cout << m << endl;

どうですか

// without setting locale to UTF8, you pass WideChars
wcout << L"¡Hola!" << endl;
// set locale to UTF8 and use cout
SetConsoleOutputCP(CP_UTF8);
cout << utf8_encoded_by_converting_using_WideCharToMultiByte << endl;
于 2010-04-05T09:53:10.437 に答える
0

簡単な答えはないと思います。Console Code PagesSetConsoleCP Functionを見る と、出力しようとしている文字セットに適切なコードページを設定する必要があるようです。

于 2010-03-31T15:41:31.663 に答える
0

英国の地域設定を使用して、Win10 で VS2017 からコンソール アプリを実行するには、次のことを行う必要がありました。

  1. VS2017 ツールを設定 > 環境 > フォントと色 > フォント: たとえば「ルシダ」
  2. C++ ソース ファイルをエンコード "Unicode (UTF-8 with signature) - Codepage 650001" で保存して、コンパイラの警告なしでアクセント付き文字リテラル L"âéïôù" を入力できるようにします。
  3. [構成プロパティ] > [一般] > [CharacterSet] > [マルチバイトを使用] および [構成プロパティ] > [C/C++] > [すべてのオプション] > [追加オプション] > [/utf-8] フラグでコンパイルします。
  4. #include <iostream>、<io.h>、および <fcntl.h>
  5. あいまいな '_setmode(_fileno(stdout), _O_WTEXT);' を実行します。アプリの開始時に 1 回
  6. 'cout <<... ;' を忘れる 「wcout << ... ;」のみを使用します

メモとして、Win7 上の VS2015 には 'SetConsoleOutputCP(65001);' が必要でした。wcout と cout を介して出力を混在させることができます。

于 2021-03-17T14:59:09.357 に答える