web-dev-qa-db-ja.com

C11およびC ++ 11でUTF-8を変換する標準的な方法は?

C11とC++ 11はどちらも、uchar.hchar16_tを明示的に16ビット幅と32ビット幅の文字として定義するchar32_t/cucharヘッダーを導入し、これらの文字タイプで文字列を書き込むためのリテラル構文u""U""をマクロ__STDC_UTF_16__と一緒に追加しました。 __STDC_UTF_32__は、UTF-16およびUTF-32コードユニットに対応するかどうかを示します。これは、一部のプラットフォームでは16ビットで一般的にUTF-16コードユニットを保持するために使用され、一部のプラットフォームでは32ビットで一般的にUTF-32コードユニットを保持するために使用されるwchar_tに関するあいまいさを取り除くのに役立ちます。これらのマクロが設定されていると仮定すると、UTF-16およびUTF-32を参照する移植性のある明確なコードを記述できます。 __STDC_ISO_10646__は、wchar_tがUTF-32値を保持できるかどうかを判断するためのプロキシとしても使用できます。それができない場合は、必ずしもUTF-16を保持しているとは限りませんが、移植可能であるためにはおそらく十分に近い近似値です。

また、マルチバイト文字とこれらのタイプを変換するための関数mbrtoc16mbrtoc32c16rtomb、およびc32rtombも追加されています。これらと既存のmbstowcsファミリーの関数の間で、UTF-16、UTF-32、プラットフォームマルチバイト文字セット、およびプラットフォームワイド文字セットの間で移植可能に変換できます(ただし、プラットフォームが定義されていない限り、必ずしも損失がないわけではありません)マルチバイトおよびワイド文字セットはUTFです。特に、ロケールで定義されたマルチバイトエンコーディングで1文字あたり2バイトを超える使用が許可されていないWindowsでは、これらの関数はかなり役に立たないようです。

さらに、リテラルUTF-8でエンコードされた文字列を書き込むためのu8""構文を追加しました。 UTF-8は、char *およびstd::stringを処理するほとんどの関数と互換性のあるエンコーディングであるため、これは最も便利な新しい追加の1つです。

ただし、UTF-8、UTF-16、およびUTF-32間で移植可能に変換する方法を追加できなかったようです。 mbtoc16および関連する関数は、実装で定義されたマルチバイトエンコーディングとUTF-16または32の間で変換します。しかし、これがUTF-8であることに依存することはできません。 Unixライクなプラットフォームでは、ロケールに依存し、それらの多くはデフォルトでロケールでUTF-8を使用します。デフォルトでなくても、知るために少なくともロケールをUTF-8ロケールに設定できます。その「マルチバイト」はUTF-8を意味します。ただし、Windowsでは、 TF-8またはロケールに2バイト以上を必要とするその他のエンコーディングを明示的に使用することはできません

何かが足りないだけですか、それともUTF-8文字列型に他の種類の文字列(プラットフォーム定義のマルチバイト、プラットフォーム定義のワイド文字、UTF-16、またはUTF-32)に変換する方法がありませんか?システムのマルチバイトエンコーディングがUTF-8であるかどうかさえ判断する方法はありませんか?このサポートが含まれなかった理由はありますか(具体的には、推測だけでなく、CまたはC++標準委員会による実際に書かれた正当化または議論を探しています)?この状況を改善するために行われている作業はありますか。将来的には改善する可能性がありますか?

または、UTF-8を移植可能な方法でサポートしたい場合、独自の実装を作成したり、ライブラリの依存関係を取得したり、iconvMultiByteToWideChar

18
Brian Campbell

std :: codecvt タイプを探しているようですね。使用法については、そのページの例を参照してください。

0
MikeP