回答
これは古い回答です。 UTF-8 Everywhere で最新のアップデートを確認できます。
意見:はい、UTF-16は有害であると見なす必要があります 。それが存在するまさにその理由は、しばらく前に、widecharが現在のUCS-4になるという誤った信念があったためです。
UTF-8の「角度中心主義」にもかかわらず、それはテキストの唯一の有用なエンコーディングと見なす必要があります。プログラムのソースコード、WebページとXMLファイル、OSファイル名、およびその他のコンピューター間のテキストインターフェイスは存在してはならなかったと主張することができます。しかし、そうする場合、テキストは人間の読者だけのものではありません。
一方、UTF-8のオーバーヘッドは、大きな利点がありますが、支払うべき小さな代償です。 char*
で文字列を渡すだけの認識されないコードとの互換性などの利点。これは素晴らしいことです。 「UTF-16ではUTF-8よりも短い便利な文字はほとんどありません。
他のすべてのエンコーディングは最終的には機能しなくなると思います。これには、MS-Windows、Java、ICU、pythonが含まれます。長い調査と議論の末、私の会社 での開発規則では、OS API呼び出し以外の場所でのUTF-16の使用が禁止されていますが、これは重要ですがアプリケーションのパフォーマンスとWindowsを使用しているという事実。変換関数は、常に想定されるUTF8 std::string
をネイティブUTF-16に変換するために開発されました。ネイティブUTF-16はWindows自体は適切にサポートされていません 。
「必要な場所で必要なものを使用する 」と言う人には、「どこでも同じエンコーディングを使用することには大きな利点があり、十分な理由がない」と言います。特に、C ++にwchar_t
を追加するのは間違いだったと思います。また、C ++ 0xにUnicodeを追加するのも間違いだと思います。ただし、STL実装に要求する必要があるのは、 std::string
またはchar*
パラメータはUnicode互換と見なされます。
「使用」にも反対です。 「あなたが望むもの 」アプローチ。そのような自由の理由はわかりません。テキストの主題については十分な混乱があり、このすべての壊れたソフトウェアになります。上記のように、プログラマーは1つの適切な方法としてUTF-8について最終的に合意に達する必要があると私は確信しています。 (私はASCIIを話さない国から来て、Windowsで育ったので、宗教的な理由に基づいてUTF-16を攻撃することが最後に予想されます。)
詳細情報を共有したいWindowsでテキストを実行する方法、およびコンパイル時にチェックされたUnicodeの正確性、使いやすさ、コードのマルチプラットフォーム性の向上のために他のすべての人に推奨することについて。この提案は、WindowsでUnicodeを使用する適切な方法として通常推奨されているものとは大幅に異なります。しかし、これらの推奨事項を詳細に調査した結果、同じ結論が得られました。
wchar_t
またはstd::wstring
を隣接するポイント以外の場所で使用しないでください。 UTF-16を受け入れるAPI。
_T("")
またはL""
UTF-16リテラルを使用しないでください(これらはIMOを標準から除外する必要があります、UTF-16非推奨の一部として)。
_UNICODE
定数に敏感な型、関数、またはそれらの派生物を使用しないでください。たとえば、LPTSTR
またはCreateWindow()
。
ただし、_UNICODE
は常に定義されています。 char*
文字列をWinAPIに渡してサイレントにコンパイルすることは避けてください
std::strings
およびchar*
プログラム内の任意の場所がUTF-8と見なされます(特に明記されていない場合)
文字列はすべてstd::string
ですが、char *または文字列リテラルをに渡すことができます。 convert(const std::string &)
。
widechars(LPWSTR
)を受け入れるWin32関数のみを使用します。 LPTSTR
またはLPSTR
を受け入れるものは絶対に使用しないでください。次の方法でパラメータを渡します:
::SetWindowTextW(Utils::convert(someStdString or "string litteral").c_str())
(ポリシーは以下の変換関数を使用します。)
MFC文字列を使用:
CString someoneElse; // something that arrived from MFC. Converted as soon as possible, before passing any further away from the API call: std::string s = str(boost::format("Hello %s\n") % Convert(someoneElse)); AfxMessageBox(MfcUtils::Convert(s), _T("Error"), MB_OK);
Windowsでのファイル、ファイル名、fstreamの操作:
パスしないでくださいstd::string
またはconst char*
ファイル名引数をfstream
ファミリに追加します。 MSVC STLはUTF-8引数をサポートしていませんが、次のように使用する必要がある非標準の拡張子があります。
std::string
引数をstd::wstring
とUtils::Convert
:
std::ifstream ifs(Utils::Convert("hello"), std::ios_base::in | std::ios_base::binary);
手動で行う必要がありますfstream
に対するMSVCの態度が変わったら、変換を削除します。
このコードはマルチプラットフォームではないため、で手動で変更する必要がある場合があります。将来
詳細については、fstream
ユニコードリサーチ/ディスカッションケース4215を参照してください。
UTF8以外のコンテンツを含むテキスト出力ファイルを作成しないでください
RAII / OODの理由から、fopen()
の使用は避けてください。必要に応じて、上記の_wfopen()
およびWinAPIの規則を使用してください。
// For interface to win32 API functions std::string convert(const std::wstring& str, unsigned int codePage /*= CP_UTF8*/) { // Ask me for implementation.. ... } std::wstring convert(const std::string& str, unsigned int codePage /*= CP_UTF8*/) { // Ask me for implementation.. ... } // Interface to MFC std::string convert(const CString &mfcString) { #ifdef UNICODE return Utils::convert(std::wstring(mfcString.GetString())); #else return mfcString.GetString(); // This branch is deprecated. #endif } CString convert(const std::string &s) { #ifdef UNICODE return CString(Utils::convert(s).c_str()); #else Exceptions::Assert(false, "Unicode policy violation. See W569"); // This branch is deprecated as it does not support unicode return s.c_str(); #endif }
コメント
回答
Unicodeコードポイントは文字ではありません! グリフ(ビジュアルフォーム)でさえない場合があります。
いくつかの例:
「ⅲ」のようなローマ数字のコードポイント。 (「iii」のように見える単一の文字。)
「á」のようなアクセント付き文字。これは、単一の結合文字「\ u00e1」または文字と分離された発音区別符号「\ u0061 \」のいずれかとして表すことができます。 u0301 “。
ギリシャ語の小文字シグマのような文字。単語の位置の中央(「σ」)と末尾(「ς」)の形式が異なりますが、検索の同義語と見なす必要があります。
Unicodeの任意のハイフンU + 00AD。コンテキストに応じて視覚的に表示される場合とされない場合があり、セマンティック検索では無視されます。
Unicode編集を取得する唯一の方法権利は、専門家によって作成されたライブラリを使用することです 、または専門家になって自分で作成することです。コードポイントを数えているだけなら、罪の状態にあります。
コメント
回答 iに対応します。 h2>
使用するUnicode変換フォーム(UTF)には簡単なルールがあります。-ストレージと通信用のutf-8-データ処理用のutf-16-あなたは行くかもしれません使用するプラットフォームAPIのほとんどがutf-32(UNIXの世界で一般的)である場合はutf-32を使用します。
今日のほとんどのシステムはutf-16(Windows、Mac OS、Java、.NET、ICU)を使用しています。 、Qt)。次のドキュメントも参照してください: http://unicode.org/notes/tn12/
「有害なUTF-16」に戻る
サロゲートを恐れている人(Unicodeを可変長エンコーディングに変換すると考えている)は、文字間のマッピングを行う他の(はるかに大きな)複雑さを理解していません。 Unicodeコードポイントは非常に複雑です。文字、合字、異体字セレクター、制御文字などを組み合わせます。
このシリーズをここで読んでください http://www.siao2.com/2009/06/29/9800913.aspx そしてUTF-16がどのように簡単な問題になるかを見てください。
コメント
回答
はい、もちろんです。
なぜですか?これは、コードの実行 と関係があります。
これらの大規模なコーパスでのコードポイント使用統計 を見るとTom Christiansenによると、「非BMPコードポイントよりも大きさが大きい場合、トランス8ビットBMPコードポイントが数桁使用されることがわかります。
2663710 U+002013 ‹–› GC=Pd EN DASH 1065594 U+0000A0 ‹ › GC=Zs NO-BREAK SPACE 1009762 U+0000B1 ‹±› GC=Sm PLUS-MINUS SIGN 784139 U+002212 ‹−› GC=Sm MINUS SIGN 602377 U+002003 ‹ › GC=Zs EM SPACE 544 U+01D49E ‹𝒞› GC=Lu MATHEMATICAL SCRIPT CAPITAL C 450 U+01D4AF ‹𝒯› GC=Lu MATHEMATICAL SCRIPT CAPITAL T 385 U+01D4AE ‹𝒮› GC=Lu MATHEMATICAL SCRIPT CAPITAL S 292 U+01D49F ‹𝒟› GC=Lu MATHEMATICAL SCRIPT CAPITAL D 285 U+01D4B3 ‹𝒳› GC=Lu MATHEMATICAL SCRIPT CAPITAL X
TDDディクタムを使用します。 「テストされていないコードは壊れたコードです」と言い換えて、「実行されていないコードは壊れたコードです」と言い換えて、プログラマーが非BMPコードポイントを処理する頻度を考えます。
UTF-16を可変幅エンコーディングとして扱わないことに関連するバグは、UTF-8 の同等のバグよりも見過ごされがちです。一部のプログラミング言語はまだUCS-2の代わりにUTF-16を提供することを保証しないでください。一部のいわゆる高レベルプログラミング言語は、コードポイントの代わりにコードユニットへのアクセスを提供します(Cを使用すると、コードポイントへのアクセスが提供されるはずです。 wchar_t
、いくつかのプラットフォームに関係なくフォームで可能です。
コメント
回答
UTF-16が有害であると見なされる可能性があると考えると、ユニコードをより深く理解する必要があると言われます 。
主観的な質問に対する私の意見を提示することに反対票を投じたので、詳しく説明させてください。UTF-16について気になるのは正確には何ですか?すべてがUTF-8でエンコードされているかどうかを確認しますか?UTF-7?またはUCS-4はどうですか?もちろん、特定のアプリケーションは、そこにあるすべての文字コードを処理するように設計されていませんが、特に今日のグローバル情報ドメインでは、国際的な境界間の通信に必要です。
しかし、実際には、UTF-16が混乱したり、不適切に実装されたりする可能性があるため(ユニコードは確かに可能です)、有害であると見なす必要があると思われる場合、どの文字エンコード方法が無害であると見なされますか?
編集:明確にするために:標準の不適切な実装が標準自体の品質を反映していると考えるのはなぜですか?他の人が後で指摘しているように、アプリケーションがツールを不適切に使用しているという理由だけで、ツールがツールを意味するわけではありませんもしそうなら、「varキーワードは有害だと考えられている」、「スレッドは有害だと考えられている」などと言えるでしょう。この質問は、標準の品質と性質を、多くのプログラマーが実装するのに苦労していることと混同していると思います。正しく使用することは、ユニコード自体ではなく、ユニコードがどのように機能するかを理解していないことに起因していると感じています。
コメント
回答
Utfに問題はありません- 16エンコーディング。しかし、16ビット単位を文字として扱う言語は、おそらく設計が不適切であると見なされるべきです。必ずしも文字を表すとは限らない「char
」という名前の型があると、かなり混乱します。ほとんどの開発者はcharタイプがコードポイントまたは文字を表すことを期待しているため、BMPを超える文字にさらされると、多くのコードが破損する可能性があります。
ただし、utf-32を使用しても、各32が意味するわけではありません。ビットコードポイントは常に文字を表します。文字を組み合わせるため、実際の文字は複数のコードポイントで構成される場合があります。 Unicodeは決して些細なことではありません。
BTW。文字が8ビットであると想定し、Utf-8でフィードされるプラットフォームやアプリケーションには、おそらく同じクラスのバグがあります。
コメント
MSに対する訴訟?)
回答
私の個人的な選択は常にUTF-8を使用します。これは、ほぼすべてのLinuxの標準です。多くのレガシーアプリとの下位互換性があります。他のUTF形式と比較して、非ラテン文字に使用される余分なスペースに関しては、オーバーヘッドが非常に少なく、ラテン文字のスペースが大幅に節約されます。ウェブ上では、ラテン語が最高の地位を占めており、当面はラテン語になると思います。そして、元の投稿の主な議論の1つに対処するために、ほぼすべてのプログラマーは、UTF-8にマルチバイト文字が含まれる場合があることを認識しています。誰もがこれを正しく処理しているわけではありませんが、通常は認識しています。これは、UTF-16で言えること以上のことです。ただし、もちろん、アプリケーションに最も適したものを選択する必要があります。そもそも複数あるのはそのためです。
コメント
回答
まあ、固定サイズのシンボルを使用するエンコーディングがあります。私は確かにUTF-32を意味します。しかし、各シンボルの4バイトは 無駄なスペースが多すぎるので、なぜ日常の状況でそれを使用するのでしょうか?
私の考えでは、ほとんどの問題は一部のソフトウェアが落ちたという事実から生じます。 Unicode標準の背後にありますが、状況をすばやく修正することはできませんでした。 Opera、Windows、Python、Qt-これらはすべて、UTF-16が広く知られるようになる前、あるいは存在する前に登場しました。ただし、Opera、Windows Explorer、およびメモ帳では、BMP以外の文字に問題がないことを確認できます(少なくとも私のPCでは)。ただし、とにかく、プログラムがサロゲートペアを認識しない場合、UTF-16は使用されません。このようなプログラムを扱うことで問題が発生しても、UTF-16自体とは関係ありません。
ただし、BMPのみをサポートするレガシーソフトウェアの問題はやや誇張されていると思います。 BMPの外部の文字は、非常に特定のケースと領域でのみ発生します。 Unicodeの公式FAQ によると、「東アジアのテキストでも、代理ペアの発生率は、平均してすべてのテキストストレージの1%未満である必要があります」。もちろん、プログラムはUnicodeに準拠していないため、BMPの外部の文字を無視しないでください 。ただし、ほとんどのプログラムは、そのような文字を含むテキストを操作することを目的としていません。それをサポートするのは不快ですが、破局ではありません。
では、別の方法を考えてみましょう。 UTF-16が存在しなかった場合、非ASCIIテキストに適したエンコーディングが得られず、UCS-2用に作成されたすべてのソフトウェアを完全に再設計してUnicode準拠を維持する必要があります。後者はおそらくUnicodeの採用を遅らせるだけでしょう。また、ASCIIに関連してUTF-8のようにUCS-2のテキストとの互換性を維持することはできなかったでしょう。
さて、すべてのレガシー問題は別として、エンコーディングに対する議論は何ですか?それ自体?私は、最近の開発者がUTF-16が可変長であることを知らないことを本当に疑っています。それは、ウィキペディアでどこにでも書かれています。誰かが複雑さを問題の可能性として指摘した場合、UTF-16はUTF-8よりも解析がはるかに難しくありません。また、UTF-16だけで文字列の長さを決定するのは簡単だと考えるのは誤りです。 UTF-8またはUTF-32を使用する場合でも、1つのUnicodeコードポイントが必ずしも1文字を意味するわけではないことに注意する必要があります。それ以外は、エンコーディングに対して実質的なものはないと思います。
したがって、エンコーディング自体が有害であると見なされるべきではないと思います。 UTF-16は、単純さとコンパクトさの間の妥協点であり、必要な場所で必要なものを使用しても害はありません .ASCIIとの互換性を維持する必要があり、UTF-8が必要な場合もあれば、Hanイデオグラフを使用して作業し、UTF-16を使用してスペースを節約したい場合もあります。また、固定を使用する文字のユニバーサル表現が必要な場合もあります。 -長さのエンコード。より適切なものを使用し、適切に実行します。
コメント
回答
特に東アジア言語での何年にもわたるWindowsの国際化作業は私を堕落させたかもしれませんが、文字列のプログラム内部表現にはUTF-16を、平文のネットワークまたはファイルストレージにはUTF-8を使用しています-ドキュメントのように。ただし、UTF-16は通常Windowsでより高速に処理できるため、「WindowsでUTF-16を使用する主な利点です。
UTF-16に飛躍することで、平均的な製品処理の適切性が劇的に向上しました。国際テキスト。サロゲートペアを考慮する必要がある狭いケースはごくわずかであり(基本的には削除、挿入、改行)、平均的なケースはほとんどストレートパススルーです。また、JISバリアントのような以前のエンコーディングとは異なり、UTF-16はサロゲートペアを非常に狭い範囲に制限するため、チェックは非常に迅速で、前後に機能します。
確かに、正しくはほぼ同じくらい高速です-エンコードされたUTF-8もあります。しかし、代理ペアを2つのUTF-8シーケンスとして誤ってエンコードする壊れたUTF-8アプリケーションも多数あります。したがって、UTF-8も救済を保証しません。
IEは、通常UTF-8ページから内部UTF-16表現に変換しますが、2000年頃からサロゲートペアを適切に処理します。I 「Firefoxでも正しく機能していると確信しているので、Operaの機能はあまり気にしません。
UTF-32(別名UCS4)は、スペースを大量に消費するため、ほとんどのアプリケーションにとって無意味です。だから、それはほとんど初心者ではありません。
コメント
回答
UTF-8は間違いなく進むべき道であり、おそらく内部用のUTF-32が付属しています。高性能のランダムアクセスを必要とするアルゴリズムで使用します(ただし、文字の組み合わせは無視します)。
UTF-16とUTF-32(およびそれらのLE / BEバリアント)はどちらもエンディアネスの問題があるため、外部で使用することはありません。
コメント
回答
UTF-16?間違いなく有害です。ここではほんの一粒ですが、プログラム内のテキストには正確に3つの許容可能なエンコーディングがあります。
コメント
。
@David:Unicode5.2は107,361個のコードポイントをエンコードします。未使用のコードポイントは867,169個あります。 ” “がばかげている場合。 Unicodeコードポイントは、UTF-16が依存するプロパティである0から0x10FFFFまでの数値として定義 されます。 (また、64ビットシステムがインターネット全体を’アドレス空間に保持できる場合、2050は128ビットシステムの見積もりを大幅に低くするようです。)
@David:” “が、128ビットスイッチではなく、Unicodeコードポイントの不足を示していた場合。次の数世紀になります。メモリとは異なり、文字が指数関数的に増加することはないため、ユニコードコンソーシアムは特に U+10FFFF
divより上のコードポイントを決して 割り当てないことを保証しています。 >。これは、21ビットで誰にとっても十分な状況の1つです。
@Simon Buchan:少なくとも最初の連絡まで。 🙂
U + FFFFより上にもコードポイントがないことを保証するために使用されるUnicode。
回答
Unicode は、最大0x10FFFF(1,114,112コード)のコードポイントを定義し、すべてのアプリケーションは多言語環境で実行されます。文字列/ファイル名などでそれを正しく処理する必要があります。
Utf-16 :1,112,064のみをカバーしますコード。 Unicode の最後にあるものは、飛行機15〜16(私用面)のものです。 Utf-16 の概念を破る以外は、今後さらに成長することはできません。
Utf-8 :理論的には2,216,757,376個のコードをカバーします。 ユニコード コードの現在の範囲は、最大4バイトのシーケンスで表すことができます。 バイトオーダー の問題は発生しません。ASCIIと「互換性があります」。
Utf-32 :理論的には2 ^ 32 = 4,294,967,296コードをカバーします。現在、可変長でエンコードされておらず、おそらく将来的にはエンコードされないでしょう。
これらの事実は自明です。 Utf-16 の一般的な使用を推奨していることを理解していません。可変長でエンコードされており(インデックスからアクセスできません)、現在でもユニコード の範囲全体をカバーするのに問題があります。バイトオーダーなどを処理する必要があります。Windowsやその他の場所でネイティブに使用されていることを除いて、利点はありません。マルチプラットフォームコードを作成する場合は、 Utf-8 をネイティブに使用し、エンドポイントでのみ変換を行う方がおそらく良いでしょう。プラットフォームに依存する方法で(すでに提案されているように)。インデックスによる直接アクセスが必要で、メモリに問題がない場合は、 Utf-32 を使用する必要があります。
主な問題は、Windows Unicode = Utf-16 を扱う多くのプログラマーがその事実を知らないか無視していないことです。可変長でエンコードされています。
* nix プラットフォームでの通常の方法は、かなり優れています。 Utf-8 として解釈されるc文字列(char *)エンコードされた幅の広いc文字列(wchar_t *) Utf-32 。
コメント
回答
これをリストに追加します:
提示されたシナリオは単純です(ここでは元のシナリオよりもさらに単純です! ):1.WinForms TextBoxは、空のフォーム上にあります。 MaxLengthが 20 に設定されています。
2。ユーザーがTextBoxに入力するか、多分テキストを貼り付けます。
3.TextBoxに何を入力または貼り付けても、20に制限されますが、20を超えるテキストでは同情的にビープ音が鳴ります(ここではYMMV、サウンドスキームを変更しました)
4.次に、テキストの小さなパケットが別の場所に送信され、エキサイティングな冒険が始まります。
これは簡単なシナリオであり、誰でも暇なときにこれを書くことができます。退屈で、これまで試したことがなかったので、WinFormsを使用して複数のプログラミング言語で自分で作成しました。そして、私はそのように配線されており、恐らく恐ろしい宇宙全体の誰よりも多くのキーボードレイアウトを持っているので、複数の実際の言語のテキストを使用します。
退屈を改善するために、フォームにマジックカーペットライド という名前を付けました。
これは、その価値のために機能しませんでした。
代わりに、次の 20 文字をマジックカーペットライド フォームに入力:
0123401234012340123𠀀
うーん。
最後の文字はU + 20000、最初の文字Unicodeの拡張Bイデオグラフ(別名U + d840 U + dc00、前で、いわば脱衣されることを恥じていない親しい友人へ)…
これでボールゲームができました。
TextBoxの場合。 MaxLength は
テキストボックスに手動で入力できる最大文字数を取得または設定します。
実際の意味は
取得または設定UTF-16LEタラの最大数テキストボックスに手動で入力でき、カプランの仲間と同じくらい夢中になっている人だけが不快に感じるという言語キャラクターの概念でかわいいゲームをプレイしようとする文字列から生きているがらくたを容赦なく切り捨てるユニット
ドキュメントの更新について試してみます… 定期的な読者 UCS-2からUTF-16 シリーズは、 TextBox.MaxLengthという単純な概念で私の不幸に気付くでしょう。 と、その厳格な動作によって不正なシーケンスが作成される場合、少なくとも.NetFrameworkの他の部分が
System.Text.EncoderFallbackExceptionをスローする可能性がある場合の処理方法:インデックス0のUnicode文字\ uD850を指定されたコードページに変換できません。*
この文字列を.Netフレームワークの他の場所に渡した場合(同僚のDan Thompsonが行っていたように)は例外です。
さて、おそらく完全な UCS-2からUTF-16シリーズ は多くの人の手の届かないところにあります。 しかしそうではありません「TextBox.Textが System.String を生成せず、.Net Frameworkの別の部分がスローされないことを期待するのは合理的ですか?つまり、コントロール自体に問題がないという、よりスマートな検証を簡単に追加できる次の切り捨てを通知するイベントの形でのチャンスがあるわけではありません。このパンクコントロールは安全契約を破っていると言っても過言ではありません。予期しない例外を引き起こしてアプリケーションを大雑把なサービス拒否として終了させることができれば、セキュリティの問題につながる可能性さえあります。WinFormsのプロセスやメソッド、またはアルゴリズムまたは手法で無効な結果が生成されますか?
ソース:マイケルS。カプランMSDNブログ
コメント
回答
必ずしもUTF-16が有害であるとは限りません。エレガントではありませんが、GB18030がGB2312で、UTF-8がGB2312で行うように、UCS-2との下位互換性という目的を果たします。 ASCII。
しかし、MicrosoftとSunが16ビット文字を中心に巨大なAPIを構築した後、途中でUnicodeの構造に根本的な変更を加えることは有害でした。変更の認識を広めることに失敗したことは、より 有害でした。
コメント
回答
UTF-16は処理とスペースの間の最良の妥協点 。これが、ほとんどの主要なプラットフォーム(Win32、Java、.NET)が文字列の内部表現に使用する理由です。
コメント
回答
UTF-16のポイントを理解したことがありません。最もスペース効率の高い表現が必要な場合は、UTF-8を使用してください。テキストを固定長として扱い、UTF-32を使用します。どちらも必要ない場合は、UTF-16を使用します。さらに悪いことに、UTF-16の一般的な(基本的な多言語平面)文字はすべて単一のコードポイントに収まるため、 UTF-16が固定長であるということは微妙で見つけにくいでしょうが、UTF-8でこれを行おうとすると、国際化しようとするとすぐにコードが速く大音量で失敗します。
回答
まだコメントできないので、utf8everywhere.org
。他のスタックエクスチェンジで十分な評判があるため、コメント権限が自動的に取得されないのは残念です。
これは、意見へのコメントを意味します:はい、UTF-16は有害であると見なす必要があります 回答。
1つの小さな修正:
UTF-8 char*
を誤ってANSI文字列バージョンのWindows-API関数に渡さないようにするには、次のことを行う必要があります。 _UNICODE
ではなく、UNICODE
を定義します。 _UNICODE
は、MessageBox
のような関数をwcslen
にマップします。
からMessageBoxW
。代わりに、UNICODE
定義が後者を処理します。証拠として、これはMS Visual Studio2005のWinUser.h
ヘッダーからのものです:
#ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif // !UNICODE
少なくとも、このエラーは、utf8everywhere.org
で修正する必要があります。
提案:
ガイドには、Wideの明示的な使用例が含まれている必要があります-データ構造の文字列バージョン。見逃したり忘れたりしにくくします。ワイド文字列バージョンの関数を使用することに加えて、ワイド文字列バージョンのデータ構造を使用すると、そのような関数のANSI文字列バージョンを誤って呼び出す可能性がさらに低くなります。
例の例:
WIN32_FIND_DATAW data; // Note the W at the end. HANDLE hSearch = FindFirstFileW(widen("*.txt").c_str(), &data); if (hSearch != INVALID_HANDLE_VALUE) { FindClose(hSearch); MessageBoxW(nullptr, data.cFileName, nullptr, MB_OK); }
コメント
回答
UCS4とUTF-32は同じです。違いますが、意味はわかります。一方はもう一方のエンコーディングです。ただし、ここでもエンディアネスの戦いが繰り広げられないように、最初からエンディアンネスを指定することを考えてほしいと思います。彼らはそれが来るのを見ることができませんでしたか?少なくともUTF-8はどこでも同じですre(誰かが6バイトの元の仕様に従っている場合を除く)。
UTF-16を使用する場合は、マルチバイト文字の処理を含める必要があります。 2Nをバイト配列にインデックス付けしてN番目の文字に移動することはできません。それをウォークするか、文字インデックスを作成する必要があります。そうしないと、バグが発生します。
C ++の現在のドラフト仕様にはUTF-32およびUTF-16には、リトルエンディアン、ビッグエンディアン、および不特定のバリアントを含めることができます。本当に? Unicodeで、誰もが最初からリトルエンディアンを実行する必要があると指定されていたとしたら、それはすべて簡単だったでしょう。 (私もビッグエンディアンで大丈夫だったでしょう。)代わりに、ある方法で実装した人もいれば、別の方法で実装した人もいました。そして今、私たちは「愚かさで立ち往生しています。ソフトウェアエンジニアになるのは恥ずかしいこともあります。
コメント
回答
開発者が十分に注意していれば、害はないと思います。 そして、彼らもよく知っているなら、このトレードオフを受け入れるべきです。
日本のソフトウェア開発者として、UCS-2は十分に大きく、スペースを制限するとロジックが単純化され、ランタイムメモリが削減されるため、UCS-2の制限の下でutf-16を使用するだけで十分です。
コードポイントとバイトが比例していると想定するファイルシステムやその他のアプリケーションがあるため、生のコードポイント番号が固定サイズのストレージに収まることが保証されます。
1つの例は、ファイル名ストレージエンコーディングとしてUCS-2 を指定する NTFSおよびVFATです。
これらの例が本当にUCS-4をサポートするように拡張したい場合は、とにかくすべてにutf-8を使用することに同意できますが、固定長には次のような良い点があります。
can長さごとにサイズを保証します(データサイズとコードポイントの長さは比例します)
ハッシュルックアップにエンコード番号を使用できます
非圧縮データは適度なサイズです(utf-32 /と比較して) UCS-4)
将来、埋め込みデバイスでもメモリ/処理能力が安い場合、余分なキャッシュミスやページ障害、余分なメモリのためにデバイスが少し遅いことを受け入れる可能性があります使用法ですが、これは近い将来には起こらないと思います…
コメント
回答
「最も人気のあるものの1つである必要がありますエンコーディング、UTF-16は有害であると見なされますか?」
かなり可能性がありますが、代替案が必ずしもはるかに優れていると見なされるべきではありません。
基本的な問題は、グリフ、文字、コードポイント、バイトシーケンスなど、さまざまな概念があることです。これらのそれぞれの間のマッピングは、正規化ライブラリを使用しても簡単ではありません。 (たとえば、ラテン語ベースのスクリプトで記述されたヨーロッパ言語の一部の文字は、単一のUnicodeコードポイントで記述されていません。これは、複雑さの最も単純な終わりです!)これは、すべてを正しくすることを意味します。非常に驚くほど難しい。奇妙なバグが予想される(そして、ここでそれらについてただうめき声を上げるのではなく、関係するソフトウェアのメンテナに 伝える)。
UTF-の唯一の方法16は、たとえばUTF-8とは対照的に、有害であると見なすことができます。UTF-8は、BMPの外部でコードポイントをエンコードする方法が異なります(サロゲートのペアとして)。コードがコードポイントにアクセスまたは反復する場合は、つまり、違いを認識する必要があります。OTOH、つまり、「文字」を想定する既存のコードの実質的な本体は、常に2バイトの量に収まる可能性があります。間違っている場合はかなり一般的な想定です。少なくとも、すべてを再構築せずに作業を続行します。言い換えると、少なくともそれらのキャラクターを見る ことができます。正しく処理されていない!
私はあなたの質問に頭を悩ませ、Unicodeのひどいシバン全体が有害であると見なされるべきであり、誰もが8ビットエンコーディングを使用するべきであると言います。私は(過去20年間で)それがつながるところを見てきました:さまざまなISO 8859エンコーディングに関する恐ろしい混乱に加えて、キリル文字とEBCDICスイートに使用されるもののセット全体、そして…まあ、そのすべての欠点に対するUnicodeはそれを打ち負かします。 「異なる国間のそのような厄介な妥協」の誤解でなければ。
コメント
_UNICODE
はまだあります:(