概要: UTF-8 エンコーディング (Windows CP 65001) で格納されたソース コードで定義された文字列リテラルをストリームcmd
を使用してコンソールに正しく出力するにはどうすればよいですか?std::cout
動機:優れたCatch 単体テスト フレームワークを (実験として) 変更して、テキストにアクセント付きの文字が表示されるようにしたいと考えています。変更は単純で信頼できるものである必要があり、作成者が機能強化として受け入れることができるように、他の言語や作業環境にも役立つ必要があります。または、Catch をご存知で、別の解決策があれば投稿していただけますか?
詳細:チェコ語版の「クイック ブラウン フォックス...」から始めましょう。
#include <iostream>
#include "windows.h"
using namespace std;
int main()
{
cout << "\n-------------------------- default cmd encoding = 852 -------------------\n";
cout << "Příšerně žluťoučký kůň úpěl ďábelské ódy!" << endl;
cout << "\n-------- Windows Central European (1250) set for the cmd console --------\n";
SetConsoleOutputCP(1250);
std::cout << "Příšerně žluťoučký kůň úpěl ďábelské ódy!" << std::endl;
cout << "\n------------- Windows UTF-8 (65001) set for the cmd console -------------\n";
SetConsoleOutputCP(CP_UTF8);
std::cout << "Příšerně žluťoučký kůň úpěl ďábelské ódy!" << std::endl;
}
以下を出力します (Lucida Console に設定されたフォント):
デフォルトのcmd
エンコーディングは 852、デフォルトの Windows エンコーディングは 1250 で、ソース コードは 65001 エンコーディング (BOM 付き UTF-8) を使用して保存されています。は、 と同じ方法で (プログラムによって) エンコーディングをSetConsoleOutputCP(1250);
変更します。cmd
chcp 1250
観察: 1250 エンコーディングを設定すると、UTF-8 文字列リテラルが正しく出力されます。説明できると思いますが、本当に不思議です。問題を解決するための適切で人間的で一般的な方法はありますか?
更新:私の"narrow string literal"
場合、Windows-1250 エンコーディングを使用して保存されます (中央ヨーロッパのネイティブ Windows エンコーディング)。ソースコードのエンコーディングには依存していないようです。コンパイラは、それをWindows のネイティブ エンコーディングで保存します。そのため、そのエンコーディングに切り替えるcmd
と、目的の出力が得られます。醜いですが、プログラムでネイティブの Windows エンコーディングを取得するにはどうすればよいですか(に渡すためSetConsoleOutputCP(cpX)
)。必要なのは、コンパイルが行われたマシンで有効な定数です。実行可能ファイルが実行されるマシンのネイティブ エンコーディングであってはなりません。
C++11 も導入されましu8"the UTF-8 string literal"
たが、適合しないようです。SetConsoleOutputCP(CP_UTF8);