UTF-8 に対して安全なコードを記述するにはどうすればよいでしょうか?

StackOverflow https://stackoverflow.com/questions/134371

質問

ASCII 文字セット用に開発された一連のアプリケーションがあります。現在、アイスランドにインストールしようとしていますが、アイスランドの文字がおかしくなるという問題に遭遇しています。

私たちは問題に取り組んでいますが、次のことが疑問に思いました。8 ビット文字用に設計され、UTF-8 データが与えられたときに適切に動作する C++ コードを記述するための優れた「ガイド」はありますか?

誰もが Unicode 標準全体を読むことを期待することはできませんが、より理解しやすいものがあれば、それをチームと共有して、このような問題が再び発生しないようにしたいと思います。

現時点では、wchar_t またはその他の文字列表現を使用するようにすべてのアプリケーションを書き直すことは実現できません。また、これらのアプリケーションはネットワークを介して 8 ビット文字を使用するサーバーやデバイスと通信するため、内部で Unicode を使用したとしても、境界での変換で問題が発生することにも注意してください。ほとんどの場合、これらのアプリケーションはデータを渡すだけです。テキストを場所から場所へコピーする以外の方法で「処理」することはありません。

使用されるオペレーティング システムは Windows と Linux です。std::string とプレーンな古い C 文字列を使用します。(そして、デザイン上の決定を擁護するように私に頼まないでください。私は混乱を解決するのを手伝おうとしているだけです。)


提案されたもののリストは次のとおりです。

役に立ちましたか?

解決

これは包括的なクイックガイドのように見えます。
http://www.cl.cam.ac.uk/~mgk25/unicode.html

他のヒント

ほとんどの場合、8 ビットクリーンである必要があります。ただし、非 ASCII 文字は複数のバイトに分割されることに注意する必要があるため、表示するテキストを改行または切り詰める場合はこれを考慮する必要があります。

UTF-8 には、マルチバイト文字のどこにいるかを常に知ることができるという利点があります。ビット 7 がセットされ、ビット 6 がリセットされた場合 (バイトが 0x80 ~ 0xBF)、これは後続バイトになります。一方、ビット 7 と 6 がセットされ、ビット 5 がリセットされた場合 (0xC0 ~ 0xDF)、先頭バイトと 1 つの後続バイトがあります。7、6、5 が設定され、4 がリセット (0xE0 ~ 0xEF) の場合、先頭バイトと後続 2 バイトというようになります。最上位ビットに設定された連続ビット数が文字を構成する総バイト数となります。あれは:

110x xxxx = 全角文字
1110 xxxx = 3 バイト文字
1111 0xxx = 4 バイト文字

アイスランド語のアルファベットはすべて ISO 8859-1、つまり Windows-1252 に含まれています。これがコンソール モード アプリケーションの場合、コンソールは IBM コードページを使用するため、(システム ロケールに応じて) 437、850、または 437、850、または 437 で表示される可能性があることに注意してください。 861. 。Windows には、UTF-8 のネイティブ表示サポートがありません。UTF-16 に変換し、Unicode API を使用する必要があります。

コンソール モード アプリケーションの場合は、コードページ 1252 を指定して SetConsoleCP および SetConsoleOutputCP を呼び出すと、問題が解決します。残念ながら、選択するコンソール フォントはコードページをサポートするフォントである必要があり、フォントを設定する方法がわかりません。標準ビットマップ フォントは、システムのデフォルトの OEM コードページのみをサポートします。

完全な Unicode は 16 ビット文字に適合しないことに注意してください。したがって、32 ビット文字を使用するか、可変幅エンコーディング (UTF-8 が最も一般的です) を使用します。

UTF-8 は、まさにユーザーの問題を念頭に置いて設計されました。注意したいのは、ASCII は実際には 7 ビット エンコーディングであるため、インフラストラクチャの一部が他の目的で 8 ビット目を使用している場合、注意が必要になる可能性があるということです。

チェックしてみてはいかがでしょうか icu. 。UTF-8 文字列の操作を容易にする関数が用意されている場合があります。

アイスランド語は ISO Latin 1 を使用するため、8 ビットで十分です。何が起こっているのかを解明するには、さらに詳しい情報が必要です。

アイスランド語は、フランス語、ドイツ語、その他の西ヨーロッパのほとんどの言語と同様、8 ビット文字セット (Windows では CP1252、*x では ISO 8859-1 別名 Latin1) を使用してサポートできます。これは Unicode が発明される前の標準的なアプローチであり、現在でも非常に一般的です。あなたが言うように、wcharを使用するようにアプリを書き換えることはできないという制約があり、その必要はありません。

UTF-8 が問題を引き起こしていることに驚かないでください。UTF-8 は非 ASCII 文字をエンコードします (例:アクセント付きのラテン文字、thorn、eth など) をそれぞれ 2 バイトとして入力します。

与えることができる唯一の一般的なアドバイスは、(理論的には) 極めて単純です。(1)サポートする文字セット(Unicode、Latin1、CP1252、...)を決定します(2)他の方法でエンコードされているデータが提供されている場合(例:UTF-8) を使用して標準にトランスコードします (例:CP1252)システムの境界(3)で、他の方法でエンコードされたデータを提供する必要がある場合、...

ワイド文字 (char の代わりに wchar_t、std::string の代わりに std::wstring) を使用することもできます。これで問題が 100% 自動的に解決されるわけではありませんが、最初のステップとしては適切です。

Unicode 対応の文字列関数も使用してください (ドキュメントを参照)。ワイド文字または文字列を操作するものは、通常、それらがワイドであることを認識します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top