忘れられたキャラクターの悲しい物語。 C ++でエンコーディングを操作するときに気を狂わせる方法





テキストといえば、ほとんどのC ++プログラマーは、文字コードの配列と、これらのコードが対応するエンコードについて考えます。 最も経験豊富な開発者はエンコーディングを指定せずにテキストの概念を考えず、経験の浅い開発者は単に文字コードが与えられたバイトの配列を考慮し、オペレーティングシステムのエンコーディングの観点から解釈します。 これら2つのアプローチの根本的な違いは、開発者の経験だけでなく、エンコードについて考えないほうがはるかに簡単であるという事実にもあります。 エンコードの保存、テキストの再コーディング、文字への自由なアクセスの取得を気にせず、同時にテキストの行を誰がどこで見ているかに関係なく、中国、米国、またはマダガスカル島でテキストのエラーのない表示を確認する方法を検討します。



8ビットおよびすべてすべて...



主なものから始めましょう。 C言語の作成者はミニマリストでした。 今日まで、C / C ++標準は「バイト」型を提供していません。 代わりに、char型が使用されます。 Charは文字、つまり文字を意味します。 したがって、C / C ++のchar型と言えば、「バイト」を意味し、その逆も同様です。 ここからが楽しみです。 実際、8ビットでエンコードされる文字の最大数は256です。これは、今日のUnicodeテーブルには数十万の文字があるという事実にもかかわらずです。



ASCIIコードの巧妙な作成者は、標準文字用に最初の128コードをすぐに予約しました。これは、英語圏のほぼすべてのものを安全にエンコードでき、必要に応じて半分のバイト、または1つの無料の高位ビットのみを残します。 その結果、コンピューターサイエンスの形成の最初の年に、誰もがこれらの残りの「負の」数値-128〜-1に到達しようとしました。 コードの各セットは特定の名前で標準化されており、その時点からエンコーディングと呼ばれていました。 ある時点で、バイト内の文字よりも多くのエンコードがあり、それらのすべては、最初の128 ASCII文字を超えた部分で互いに互換性がありませんでした。 その結果、エンコーディングを推測しない場合、アメリカのコミュニティにとって不可欠なシンボルのセットではないものはすべて、いわゆるkrakozyabrasの形式で表示されます。これは、一般に読めない文字です。



さらに、同じアルファベットに対して、異なるシステムが、同じ会社に属する2つのシステムであっても、互いに完全に一貫性のないエンコーディングを導入しました。 したがって、MS DOSのキリルアルファベットには855および866が使用され、Windowsには1251が既に使用され、Mac OSの同じキリルアルファベットにはすべて独自のエンコーディングがあり、KOI8およびKOI7はそれらとは区別され、ISO 8859-5もあります。同じ文字セットをまったく異なる文字で扱います。 さまざまなバイト文字を処理するときに、たとえばウムラウトを使用してロシア語からドイツ語に翻訳するときに、いくつかのエンコードを使用することが不可能であっただけでなく、一部のアルファベットの文字自体は、残りの128の位置に収まりたくありませんでした。 その結果、国際的なプログラムでは、文字が異なるエンコーディングで解釈され、隣接する行であっても、どのエンコーディングのどの行を覚えている必要があり、必然的にテキストの表示エラーを引き起こしました。



デフォルトでUTF-8を使用するLinuxがある場合、ホストシステムとは異なるエンコードを使用する他のオペレーティングシステムを仮想マシンに配置します(例:エンコード1251を使用するWindows、またはその逆)。 std :: coutのキリル文字列の出力を使用してコードを記述してみてください。コードを変更せずにビルドし、両方のシステムで同じように動作します。 同意して、クロスプラットフォームコードを国際化することはそれほど簡単な作業ではありません。


ユニコードの到来



Unicodeのアイデアはシンプルでした。 各文字は1つのコードに割り当てられ、永久に1つのコードに割り当てられます。これはUnicode文字テーブル仕様の次のバージョンで標準化され、文字コードは1バイトに制限されなくなりました。 1つを除くすべての素晴らしいアイデア:C / C ++プログラミング言語とそれらの言語では、char文字はバイトに関連付けられていました。 コード全体で、sizeof(char)は1に等しくなりました。 テキストの行は、これらの同じ文字の通常のシーケンスであり、コードがゼロの文字で終わります。 C、リッチー、カーニガンの言語の作成者を擁護するために、1970年代にはタイプライターの文字をエンコードするのに十分なバイトであるため、文字をエンコードするのにそれほど多くのコードが必要になるとは考えられなかったと言わなければなりません。 可能性として、主な悪が作成されました;型charを変更すると、すでに記述されたコードとの互換性が失われます。 合理的な解決策は、新しいタイプの「ワイド文字」wchar_tを導入し、新しい「ワイド」行を操作するためのすべての標準C関数を複製することでした。 コンテナライブラリの標準C ++文字列でも、「ワイド」な兄弟wstringが見つかりました。



誰もが1つの「しかし」ではないにしても幸せです。誰もがすでにバイト文字列に基づいてコードを記述することに慣れており、文字列リテラルの前のLプレフィックスはC / C ++開発者に熱意を加えませんでした。 人々は、ASCIIタイプ以外の文字を使用せず、char型で動作する既に記述されたコードと互換性のない異常な構造を記述するよりも、ラテンアルファベットの制限に耐えることを好みました。 状況を複雑にするために、wchar_tには標準化されたサイズがありません。たとえば、最新のg ++​​ GCCコンパイラーでは4バイトであり、Visual C ++では2バイトであり、Android NDK開発者はそれを1バイトにトリミングし、charと区別できないようにしました。 どこでも動作しないまあまあの解決策であることが判明しました。 デフォルトでは1つのwchar_tが1つのUnicode文字に対応する必要があるため、4バイトのwchar_tが真理に最も近い一方で、wchar_tを使用するコードに正確に4バイトがあることを保証する人はいません。



別の解決策は、UTF-8のシングルバイトエンコーディングでした。これは、ASCII(最上位ビットであるゼロ)がシングルバイト文字に対応しているだけでなく、最大4バイトの整数、つまり20億文字以上をエンコードすることもできます。 ただし、ボードは非常に大きく、文字はさまざまなサイズで取得されます。たとえば、ラテン文字Rをロシア文字Iに置き換えるには、行全体を完全に再構築する必要があります。これは、4バイトwchar_tの場合の通常のコード置換よりもはるかに高価です。 したがって、UTF-8の文字列文字を使用したアクティブな作業は、このエンコードを使用するという考えに終止符を打つことができます。 それにもかかわらず、エンコーディングはテキストを非常にコンパクトに圧縮し、読み取りエラーに対する保護を含み、最も重要なことは国際的です:UTF-8でエンコードされた文字列を読み取ると、世界中の誰もがUnicodeテーブルから同じ文字を見ることになります。 もちろん、この行を別のエンコーディングで解釈しようとする場合を除き、Windows 1251でUTF-8のキリル文字アルファベットをデフォルトのエンコードテキストとして開こうとすると、誰もが「krakozyabry」を覚えています。



Unicodeシングルバイトデバイス



UTF-8エンコーディングは非常に面白いものです。 基本的な原則は次のとおりです。



  1. 文字は一連のバイトによってエンコードされます。各バイトの先頭ビットは、シーケンス内のバイトの位置をエンコードし、最初のバイトについては、シーケンスの長さもエンコードします。 たとえば、UTF-8では、文字は次のようになります。[1101 0000] [1010 1111]
  2. 2番目から始まるシーケンスのバイトは常にビット10で始まり、各文字のコードシーケンスの最初のバイトは10で始まることはできません。 これは、UTF-8からの文字コードのデコードの基本的な検証の基礎です。
  3. 最初のバイトが1つだけである場合、先頭ビットは0であり、文字はASCIIコードに対応します。これは、エンコードのために7つの最下位ビットが残っているためです。
  4. 文字がASCIIでない場合、最初のビットには、先頭バイトを含むシーケンス内のバイトと同じ数のユニットが含まれ、その後にユニットシーケンスの終わりとして0が続き、次に最初のバイトの有効ビットが続きます。 上記の例からわかるように、文字Iのエンコードには2バイトかかります。これは、シーケンスの最初のバイトの上位2ビットで認識できます。
  5. すべての重要なビットはビットの単一のシーケンスに接着されており、すでに数値として解釈されています。 たとえば、2バイトでエンコードされた文字の場合、条件付きで重要なビットに文字xをマークします。[110x xxxx] [10xx xxxx]


ご覧のとおり、接着すると、11ビットでエンコードされた数値、つまりUnicodeテーブル文字の最大0x7FFを取得できます。 これは、0x400から0x530の範囲のキリル文字の文字には十分です。 例からシンボルIを接着すると、コードが得られます:1 0000 10 1111



Unicode文字テーブルの文字コードIは、0x42Fだけです。



つまり、文字列内の文字を操作せず、Unicodeテーブルの他の文字に置き換えた場合、UTF-8エンコードを使用できます。文字列の要素がバイトと同じサイズであるという意味で、信頼性、コンパクト、char型との互換性がありますが、それらは必ずしもシンボルではありません。



実際、UTF-8エンコードの効率と人気がAndroid NDKでのシングルバイトwchar_tの強制導入を決定し、開発者はUTF-8を使用するように促し、「ワイド」行はそれを実行可能なタイプとして認識しません。 一方、GoogleはC ++で例外を否定していませんでしたが、少なくとも3倍のGoogleであり、例外処理をサポートしなければならなかったとしても、全世界と議論することはありません。 サイズが1バイトのwchar_t文字に関しては、多くのライブラリは既にwchar_t型の試練に慣れており、通常のバイト文字列を処理することにより「ワイド」機能を複製します。



UTF(Unicode Transformation Format)-基本的に、Unicodeテーブルの文字コードを使用して、標準化されたルールに従ってバイト配列にパックされたテキストのバイト表現。 最も一般的なのはUTF-8とUTF-16で、それぞれ8ビットと16ビットの要素を持つ文字を表します。 どちらの場合も、シンボルは必ずしも正確に8または16ビットを占有するわけではありません。たとえば、UTF-16では、サロゲートペアが使用され、実際には16ビット値のペアが一緒に使用されます。 その結果、文字を表すグループのビットよりも少ない有効ビット(サロゲートペアの場合は20)が少なくなりますが、文字をエンコードする機能は256または65,536の値の制限を超え始め、Unicodeテーブルの任意の文字をエンコードできます。 相当するものとは異なり、UTF-32は、大量のテキストにとって重要なデータ表現の冗長性のため、あまり人気がありません。


コードにロシア語で書いています



ASCII以外の言語のコードで行を使用しようとすると、言語に基づく不幸と差別が始まります。 そのため、Visual Studio for Windowsはデフォルトですべてのファイルをファイルシステムエンコーディング(1251)で作成し、デフォルトのエンコーディングUTF-8を使用して同じLinuxでロシア語の行でコードを開こうとすると、ソーステキストの代わりに奇妙な文字の束を取得します。



状況は、Visual Studioがキリル文字を含む「幅の広い」行を非常に独特な方法で解釈し始めることなく、必須のBOM文字を含むUTF-8エンコードでソースコードを再保存することによって部分的に保存されます。 ただし、UTF-8エンコーディングのBOM(バイトオーダーマーク)が3バイト0xEF、0xBB、および0xBFでエンコードされた文字であると指定すると、どのシステムでもUTF-8エンコーディングが認識されます。



BOMは、Unicodeテキストエンコーディングを認識するために必要なバイトの標準ヘッダーセットであり、UTFエンコーディングごとに外観が異なります。 プログラムで母国語を自由に使用してください。 他の国にローカライズする必要がある場合でも、国際化メカニズムは、ある言語の文字列を別の言語の文字列に変換するのに役立ちます。 もちろん、これは製品がロシア語セグメントで開発されている場合です。



文字列定数と中間テキスト値の保存と処理の両方に「ワイド」文字列を使用してみてください。 文字列内の要素数と文字数を一致させるだけでなく、効果的な文字置換は費用がかかります。 はい、それでもすべてのライブラリが「ワイド」文字で動作することを学んだわけではなく、一連のライブラリ全体がBoostで遭遇します。そこではワイド文字列のサポートが不注意に行われますが、状況は修正されています、主にライブラリトラッカーでエラーを書いている開発者のおかげで、ライブラリ開発者のウェブサイトのエラーを修正します。



キリル文字で関数名と同様に、定数と変数を記述する必要はまだありません。 ネイティブ言語で定数を導出することと、常にレイアウトを切り替えてコードを記述することはまったく別のことです。 最良の選択肢ではありません。



タイプ「バイト」とタイプ「テキスト」を区別します



留意すべき主なことは、タイプ「テキスト」がタイプ「バイトセット」と根本的に異なることです。 メッセージ行について話している場合、これはテキストです。また、何らかのエンコーディングのテキストファイルについては、テキストとして減算できるバイトのセットです。 ネットワークを介してテキストデータが届くと、エンコードと一緒に、正確にバイトが届き、これらのバイトからテキストを取得する方法がわかります。



Python 3をPython 2と比較して見ると、3番目のバージョンは、これら2つの概念を分離し、開発において真に重大な飛躍を遂げています。 経験豊富なC / C ++開発者であっても、Python 3で少し作業して、Pythonの言語レベルでテキストとバイトの分離の深さを体験することを強くお勧めします。 実際、Python 3のテキストはエンコーディングの概念から分離されており、C / C ++開発者にとって非常に珍しいと思われます。Python3の文字列は世界のどこでも同じように表示され、この文字列をエンコーディングで表現したい場合は、テキストを変換する必要がありますエンコードを示す一連のバイト。 この場合、実際には、str型のオブジェクトの内部表現は、内部表現がUnicodeで格納され、エンコードに変換する準備ができていることを理解するほど重要ではありませんが、byte型のバイトのセットの形式です。



C / C ++では、同様のメカニズムにより、Python 3が第2バージョンに関して許可した下位互換性の喪失などの贅沢の欠如を防ぐことができます。 標準の次のリビジョンのいずれかで、char型をwchar_tとbyteの類似体に分割するだけで、言語が崩壊し、膨大な量の既に記述されたC / C ++コードとの互換性が失われます。 より正確には、あなたが現在取り組んでいるすべてのもの。



変なトランスコーディング



したがって、元の問題は未解決のままでした。 UTF-8、およびWindows 1251エンコーディングのような古くて不親切なシングルバイトエンコーディングの両方のシングルバイトエンコーディングがまだあります。一方、文字列定数をワイド文字列として設定し、wchar_t-「ワイド」文字でテキストを処理します。



ここで、再コーディングのメカニズムが役立ちます。 結局、バイトセットのエンコードを知っていれば、いつでもwchar_t文字セットに変換したり、その逆を行うことができます。 急いで自分で変換ライブラリを作成しないでください。最新版のUnicodeコード表全体のように、あらゆるエンコーディングの文字コードがすぐに見つかることを理解しています。 ただし、変換ライブラリはそれなしで十分です。 LGPLの下でライセンスされているクロスプラットフォームライブラリlibiconvがあり、これはクロスプラットフォーム開発でこれまでで最も人気があります。 再コーディングはいくつかの指示に削減されます。



iconv_t conv = iconv_open("UTF-8","CP1251"); iconv(conv, &src_ptr, &src_len, &dst_ptr, &dst_len); iconv_close(conv);
      
      





したがって、まず、あるエンコーディングから別のエンコーディングへのトランスコーディングハンドラの作成、次にあるバイトセットから別のバイトセットへのトランスコーディング操作(バイトセットの1つが実際にwchar_t配列のバイトであっても)、その後、作成されたトランスコーディングハンドラを閉じることが必須です。 また、より野心的なICUライブラリもあります。これは、トランスコーディングを操作するためのC ++インターフェイスと、Unicode表現でテキストを直接保存するための特別なタイプicu :: UnicodeStringの両方を提供します。 ICUライブラリもクロスプラットフォームであり、その使用オプションはさらに1桁多く提供されています。 C ++ APIライブラリを使用する場合、ライブラリ自体がトランスコーディング用のハンドラの作成、キャッシュ、および使用を処理するのは素晴らしいことです。



たとえば、Unicodeで文字列を作成するには、icu :: UnicodeStringクラスの通常のコンストラクターを使用することが提案されています。



 icu::UnicodeString text(source_bytes, source_encoding);
      
      





したがって、wchar_t型を完全に放棄することが提案されています。 ただし、問題は、このような文字列の内部Unicode表現が2バイトに設定されることであり、コードがこれらの2バイトを超える場合に問題が発生します。 さらに、icu :: UnicodeStringインターフェースは標準のwstringとは完全に互換性がありませんが、C ++開発者にとってICUを使用することは良いオプションです。



さらに、mbstowcsとwcstombsの標準関数がいくつかあります。 一般に、ロケールが正しく定義されていれば、それらはそれぞれ(マルチ)バイト文字列を「ワイド」に、またはその逆に変換します。 略語mbsとwcsは、それぞれマルチバイト文字列とワイド文字列としてデコードされます。 ちなみに、C言語開発者になじみのある文字列操作関数のほとんどは、strが名前のwcsに置き換えられた関数(strlenの代わりにwcslen、strcpyの代わりにwcscpyなど)によって複製されます。



Windows開発を思い出すしかありません。 WinAPIの受賞者は、WideCharToMultiByteとMultiByteToWideCharという一連のパラメーターを持つ別の関数ペアをお楽しみいただけます。 これらの関数は、その名前のとおりに機能します。 エンコード、入力および出力配列のパラメーター、およびフラグを示し、結果を取得します。 これらの機能は見苦しいにもかかわらず、迅速かつ効率的に機能します。 確かに、常に正確であるとは限りません。文字を類似の文字に変換しようとする場合があるため、関数に2番目のパラメーターによって渡されるフラグでWC_NO_BEST_FIT_CHARSを指定することをお勧めします。



使用例:



 WideCharToMultiByte( CP_UTF8, WC_NO_BEST_FIT_CHARS, pszWideSource, nWideLength, pszByteSource, nByteLength, NULL, NULL );
      
      





もちろん、このコードはWindows以外のプラットフォームには移植できないため、ICU4Cまたはlibiconvクロスプラットフォームライブラリを使用することを強くお勧めします。



最も一般的なライブラリはlibiconvですが、char *パラメーターのみを使用します。 これは恐ろしいことではありません。どんな場合でも、ビットの数の配列は単なるバイトのセットです。 ただし、2バイト以上の数字の方向を覚えておいてください。 つまり、バイト配列のどの順番でバイトがバイト-数のコンポーネントになります。 それぞれビッグエンディアンとリトルエンディアンを区別します。 大多数のマシンで一般的に受け入れられている数値表現の順序は、リトルエンディアンです。最初に下位バイトが来て、最後に数値の上位バイトが来ます。 ビッグエンディアンは、通常、上位バイト(オーバーヘッド情報を含むことが多い)から最年少で終わる番号で送信されるネットワークを介してデータ転送プロトコルを使用する人には馴染みがあります。 UTF-16、UTF-16BE、UTF-16LEは同じものではないことに注意してください。


テキストクラス



取得した知識を蓄積し、元の問題を解決しましょう。「ワイド」またはバイトの文字列で初期化されたエンティティを本質的に作成し、エンコードを使用して、文字列std :: stringの通常のコンテナへのインターフェースを提供し、要素にアクセスする必要があります-文字、それらの変更、削除、文字列内のテキストのコピーの「ワイド」としての変換、およびエンコードされたバイト。 一般的に、一方ではユニコードの操作を大幅に簡素化し、他方では以前に作成したコードとの互換性を確保する必要があります。



したがって、テキストクラスは次のコンストラクタを受け取ります。



 text(char const* byte_string, char const* encoding); text(wchar_t const* wide_string);
      
      





また、std :: stringおよびstd :: wstringオプション、およびソースコンテナの先頭と末尾のイテレータからもオーバーロードする価値があります。



エレメントへのアクセスは明らかに開いている必要がありますが、結果としてバイト文字またはプラットフォーム依存のwchar_tを使用することはできません。Unicodeテーブルの整数コードの抽象化:シンボルを使用する必要があります。



 symbol& operator [] (int index); symbol const& operator [] (int index) const;
      
      





したがって、Unicode文字列をcharまたはwchar_t文字列として保存できないことが明らかになります。 少なくともstd :: basic_string <int32_t>が必要です。これは、現在UTF-8およびUTF-16エンコーディングがUTF-32は言うまでもなくint32_t内の文字をエンコードするためです。



一方、テキストクラス以外では `std :: basic_string <int32_t>`は必要ありません。`unicode_string`と呼びましょう。 すべてのライブラリは、 `std :: string`および` std :: wstring`または `char const *` `and` wchar_t const *`で動作します。 したがって、着信std :: stringまたはstd :: wstringの両方と、テキストをバイト文字列エンコードに変換した結果をキャッシュするのが最善です。 さらに、多くの場合、テキストクラスは、データベースからJSON文字列へのUTF-8のバイトなど、移動文字列の一時的なストレージとしてのみ必要です。つまり、要素にアクセスするためのリクエストでのみunicode_stringにトランスコードする必要があります-テキストの文字。 テキストとその内部表現は、集中的な使用を伴うため、最大限の最適化が必要なクラスであり、理由もなく最初の要件まではトランスコーディングを許可しません。 テキストクラスAPIのユーザーは、特定のエンコーディングでテキストをバイト文字列に変換するか、システム全体の「ワイド」文字列を取得することを明示的に指定する必要があります。



 std::string const& byte_string(std::string const& encoding) const; std::wstring const& wide_string() const;
      
      





上記のように、計算してクラスフィールドに保存した文字列へのリンクを返しています。 もちろん、少なくとも1文字の値の最初の変更時に、 `std :: string`と` std :: wstring`でキャッシュをクリーンアップする必要があります。ここで演算子->定数でないthisデータクラス `text :: data`が役立ちます。 これを行う方法については、C ++ Academyの前の2つのレッスンを参照してください。



また、std :: stringおよびstd :: wstringがクラステキストのフィールドによってキャッシュされている場合、char const *およびwchar_t const *を取得することも忘れないでください。



 char const* byte_c_str(char const* encoding) const; wchar_t const* wide_c_str() const;
      
      





実装は、それぞれbyte_stringとwide_stringの結果に対して `c_str()`を呼び出すことに要約されます。



UTF-8バイト文字列のデフォルトエンコーディングと見なすことができます。システムのデフォルトエンコーディングを使用するよりもはるかに優れているため、コードはシステムによって異なる動作をします。 バイト文字列を操作するときにエンコードを指定せずにいくつかの追加のオーバーロードを導入することにより、代入演算子をオーバーライドする機会も得られます。



 text& operator = (std::string const& byte_string); //   ”UTF-8” text& operator = (std::wstring const& wide_string);
      
      





また、+演算子と+ =演算子のオーバーロードについても覚えておく必要がありますが、一般的に、残りの操作は既に引数とテキスト型の結果、つまりエンコードに関係なくテキストを提供する普遍的な値に還元できます。



もちろん、自分でテキストクラスを実装することを提案していなければ、C ++アカデミーはアカデミーではなかったでしょう。 この記事の資料に基づいてテキストクラスを作成してみてください。 実装は、2つの単純なプロパティを満たしている必要があります。





ここでは、追加の定数でない「演算子->」を処理して、キャッシュを行でリセットするのが理にかなっていますが、これは開発者の裁量に任せます。 それはあなたです。 頑張って



もちろん、以前の記事のcopy_on_writeクラスがなければ実装はできません。 いつものように、念のため、その簡略化されたビューを思い出します。



 template <class data_type> class copy_on_write { public: copy_on_write(data_type* data) : m_data(data) { } data_type const* operator -> () const { return m_data.get(); } data_type* operator -> () { if (!m_data.unique()) m_data.reset(new data_type(*m_data)); return m_data.get(); } private: std::shared_ptr<data_type> m_data; };
      
      





何を得る



テキストクラスを実装することにより、多くのエンコーディングから抽象化されます。必要なのは、テキストクラスからの1つのオーバーロードだけです。 たとえば、次のように:



 text to_json() const; void from_json(text const& source);
      
      





`std :: string`と` std :: wstring`からのオーバーロードはもう必要ありません。「ワイド」文字列のサポートに切り替える必要はありません。文字列リンクをAPIのテキストに置き換えるだけで、Unicodeが自動的に取得されます。 さらに、トランスコーディングエンジン、ICU4Cまたはlibiconvとして選択したライブラリに関係なく、優れたクロスプラットフォームの動作が得られます。これは、文字を展開するときに内部表現が常にUTF-32であり、プラットフォーム固有のものに結び付けられていないためですwchar_t。



合計:標準型との互換性または相互変換があるため、C ++で記述されたコード側のUnicodeサポートが簡素化されます。 結局、C ++で高レベルのロジックを記述する場合、最後に取得したいのは、テキストを処理およびトランスコードするときにwchar_t文字と単調なコードを使用するときの問題です。



変換自体はすでに同じICU4Cとlibiconvで実装されていますが、テキストクラスの内部操作のアルゴリズムは非常に単純です。 先に進むと、おそらく明日は、クライアントからの単純なJSONからさまざまなデータベースからの複雑なテキスト構造に至るまで、あらゆるテキストデータの処理における高レベルの抽象化としてどこでも使用されるテキストライブラリです。



画像



Hacker Magazine#191で最初に発行されました。

投稿者:Vladimir Qualab Kerimov 、リーディングC ++開発者、Parallels



ハッカーを購読する




All Articles