web-dev-qa-db-ja.com

UnicodeはC ++ 11でどの程度サポートされていますか?

C++ 11がUnicodeをサポートしていることを読んで聞いたことがあります。それに関するいくつかの質問:

  • C++標準ライブラリはUnicodeをどの程度サポートしていますか?
  • std::stringは必要なことを行いますか?
  • どうやって使うの?
  • 潜在的な問題はどこにありますか?
169
Ralph Tandetzky

Unicodeは標準ライブラリではサポートされていません(サポートされる合理的な意味のため)。

std::stringstd::vector<char>よりも優れているわけではありません。Unicode(またはその他の表現/エンコード)を完全に無視し、そのコンテンツをバイトのblobとして単純に扱います。

ブロブの保存と分類のみが必要な場合は、かなりうまく機能します。しかし、Unicode機能(コードポイントの数、グラフェンの数など)を望むとすぐに、あなたは運が悪くなります。

私がこれについて知っている唯一の包括的なライブラリはICUです。ただし、C++インターフェースはJavaインターフェースから派生したものであるため、慣用的ではありません。

37
Matthieu M.

Unicode NUL(U + 0000)はUTF-8ではnullバイトであり、これが唯一であるという事実により、UTF-8をstd::string(または、その場合はchar[]またはchar*)に安全に保存できます。 UTF-8ではヌルバイトが発生する可能性があります。したがって、UTF-8文字列はすべてのCおよびC++文字列関数に従って適切に終了され、C++ iostream(ロケールがUTF-8である限りstd::coutおよびstd::cerrを含む)を使用してそれらを囲むことができます。

UTF-8のstd::stringでできないことは、コードポイントの長さを取得することです。 std::string::size()は、文字列の長さをbytesで示します。これは、UTF-8のASCIIサブセット内にあるときのコードポイントの数に等しいだけです。

UTF-8文字列をコードポイントレベルで操作する必要がある場合(保存および印刷するだけでなく)、または内部NULLバイトを多く持つ可能性が高いUTF-16を扱う場合は、ワイド文字列タイプを調べるため。

22
uckelman

C++ 11には、Unicode用の 新しいリテラル文字列型 がいくつかあります。

残念ながら、標準ライブラリでの非均一エンコーディング(UTF-8など)のサポートは依然として不十分です。たとえば、UTF-8文字列の長さ(コードポイント)を取得する良い方法はありません。

ただし、 tiny-utf8 と呼ばれる非常に便利なライブラリがあり、これは基本的にstd::string/std::wstringdrop-in replacementです。まだ欠落しているutf8-stringコンテナクラスのギャップを埋めることを目的としています。

これは、utf8文字列を使用して(つまり、Unicodeの正規化や同様のものを使用せずに)「処理」する最も快適な方法です。文字列はrun-length-encoded charsでエンコードされたままですが、快適にcodepointsを操作します。

3
Jakob Riedle