2013-06-05 20 views
7

Linux端末でユニコード文字をiostreamで印刷する必要があります。しかし、奇妙なことは起こる。私が書くとき:C++のユニコード文字の印刷

cout << "\u2780"; 

を私が取得:を、ほぼ正確に私が欲しいものです。しかし、私が書く場合:

cout << '\u2780'; 

私は得る:14851712

問題は、私はコンパイル時に印刷される正確な文字を知らないということです。印刷し

int x; 
// some calculations... 
cout << (char)('\u2780' + x); 

したがって、私のような何かをしたいと思います。代わりにwcoutまたはwchar_tを使用すると、どちらも動作しません。正しい印刷方法を教えてください。

インターネットで見つかったことから、私はg ++ 4.7.2コンパイラをDebian Wheezyリポジトリから直接使用することが重要と思われます。

+0

は、オペレータ 'L'でwchar_tを使用していますか?可能であれば完全なコードを投稿するか、[sscce.org](SSCCE) – pinkpanther

+0

Unicodeエンコーディングを混乱させたくない場合は、文字列を追加するのではなく、 'x'の値にマップすることができます。 – dyp

+0

[C++でUnicode文字を印刷するにはどうすればいいですか?](http://stackoverflow.com/questions/12015571/how-to-print-unicode-character-in-c) –

答えて

6

Unicode文字\u2780は、charデータ型の範囲外です。あなたは、単一のユニットとしてU + 2780のような文字で作業する場合は、する必要があります(少なくとも私のG ++ 4.7.3がそれを与える)

test.cpp:6:13: warning: multi-character character constant [-Wmultichar] 

を:あなたはそれをご紹介するために、このコンパイラの警告を受けているはずですwidecharデータ型wchar_tを使用するか、C++ 11、char32_t、またはchar16_tを使用できるほど幸運な場合は、使用してください。 1つの16ビット単位では、Unicode文字の全範囲を表すには不十分であることに注意してください。

これはうまくいかない場合は、デフォルトの「C」ロケールで非ASCII出力がサポートされていない可能性があります。この問題を解決するには、プログラムの最初にsetlocaleと呼ぶことができます。そのように出力することができ、ユーザーのロケールによってサポートされている文字のフルレンジ:(またはお使いのすべての文字をサポートしていないこともある)

#include <clocale> 
#include <iostream> 

using namespace std; 

int main() { 
    setlocale(LC_ALL, ""); 
    wcout << L'\u2780'; 
    return 0; 
} 
+0

もちろん同じ問題があるかもしれません'sizeof(wchar_t)<4'ならば他の文字(SMP) 'char16_t'または' char32_t'btwを使うことをお勧めします。 – dyp

+2

に加えて、エンコーディング接頭辞 'L'には、' UTF8'エンコーディングの 'u8'、' char16_t'の 'u'、' char32_t'の 'U'があります。 – Appleshell

+0

'' ''をロケール名に渡すときに 'setlocale'がユーザの優先ロケールを設定します。これは必ずしもUnicodeロケールである必要はありません。 – dyp

4

次のように記述すると

cout << "\u2780"; 

ザ・コンパイラは\ u2780を実行文字セット内のその文字の適切なエンコーディングに変換します。これはおそらくUTF-8なので、文字列は4バイト(文字の場合は3つ、ヌルターミネーターの場合は1つ)を持つことになります。

実行時に文字を生成する場合は、実行時にコンパイラがコンパイル時に行うUTF-8と同じ変換を行う必要があります。


C++ 11には、しかしにlibstdC++、GCCに付属している標準ライブラリの実装は、まだ(GCC 4.8のように)それらを実装するに周り得ていないが、これを行うことができ便利wstring_convertテンプレートとcodecvtファセットを提供します。以下は、これらの機能の使用方法を示していますが、別の標準ライブラリ実装を使用するか、libstdC++がそれらを実装するのを待つ必要があります。

#include <codecvt> 

int main() { 
    char32_t base = U'\u2780'; 

    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert; 
    std::cout << convert.to_bytes(base + 5) << '\n'; 
} 

利用可能なUTF-8を作成する他の方法を使用することもできます。たとえば、iconv、ICU、およびpre-C++ 11 codecvt_bynameファセットの手動使用はすべて動作します。 (そのコードがwstring_convertで許可され、簡単なコードよりも複雑になるので、私はこれらの例を示していない。)


文字の数が少ないために働くだろう代替の配列を作成することですリテラルを使用している文字列。

char const *special_character[] = { "\u2780", "\u2781", "\u2782", 
    "\u2783", "\u2784", "\u2785", "\u2786", "\u2787", "\u2788", "\u2789" }; 

std::cout << special_character[i] << '\n'; 
0

プログラムが原因でC++ 11§2.14.3/ 1の整数を印刷:

で表現できない単一のC-チャーを含むリテラル複数文字リテラル、または通常の文字条件付きでサポートされ、型intを持ち、実装定義の値を持ちます。

実行文字セットは、charが表すことができるもの、つまりASCIIです。

あなたが入手したのは14851712、またはU + 2780のUTF-8表現である16進数e29e80です。 intにマルチバイトエンコーディングのUTF-8を入れることは、狂ったばかげたことですが、これは "条件的にサポートされた実装定義の"機能から得られるものです。

UTF-32値を取得するには、U'\u2780'を使用します。最初のUは、char32_tタイプとUTF-32エンコーディングを指定します(つまり、最大31ビットですが、サロゲートペアはありません)。 2番目の\uは、コードポイントを含む汎用文字名を指定します。 wcoutと互換性のある値を取得するには、L'\u2780'を使用してください。ただし、必ずしもUnicodeランタイム値を使用するわけではありません。

Unicodeコードポイントを確実に操作して印刷するためには、他の回答が指摘しているように、C++標準はそれほどまだ得られていません。 Joniの答えは最良の方法ですが、コンパイラとユーザーの環境が同じロケールを使用していることが前提ですが、これはしばしば真実ではありません。

u8"\u2780"を使用してソースでUTF-8文字列を指定し、実行時環境をstd::locale::global(std::locale("en_US.UTF-8"));などを使用してUTF-8に設定することもできます。しかし、それはまだ荒い縁を持っています。 Joniは、C++インターフェイスstd::locale::globalから<locale>の代わりに<clocale>のCインターフェイスstd::setlocaleを使用することを提案しています。これは、OS Xや他のプラットフォームのGCCでC++インターフェイスが壊れてしまう可能性を回避する方法です。この問題は、あなたのLinuxディストリビューションがパッチを自分のGCCパッケージに入れても十分なほどプラットフォームに敏感です。 Linuxの場合

+0

コンパイラが「Uはスコープで宣言されていません」と強く勧めているので、あなたか私はおそらく何かを見逃していました。 – Sventimir

+0

@Sventimir明らかに、GCC 4.7.2ではサポートされていませんが、C++ 11標準の一部です。ちょうど 'L'xxx''と一緒に行け; Linuxでは本質的に同じことを行う必要があります。 – Potatoswatter

+0

'gcc --std = C++ 11'呼び出しでC++ 11サポートを追加することもできません。これはコンパイルされますが、char自体ではなくchar(10112)の10進値が出力されます。 – Sventimir

0

、私が最も素朴な方法のように、直接任意のUnicodeをプリントアウト成功している:

std::cout << "ΐ , Α, Β, Γ, Δ, ,Θ , Λ, Ξ, ... ±, ... etc" 
関連する問題