C++_string_handling

}}
C ++プログラミング言語はのためのサポートがある文字列処理を主にその中に実装され、標準ライブラリ。言語標準では、いくつかの文字列タイプが指定されています。一部はCから継承され、一部はクラスやRAIIなどの言語の機能を利用するように設計されています。これらの中で最もよく使用されるのはstd :: stringです。
C ++の初期バージョンには「低レベル」のC文字列処理機能と規則しかなかったため、文字列処理クラスの互換性のない複数の設計が長年にわたって設計され、代わりに使用されていますstd::string。C++プログラマーは複数の規則を処理する必要がある場合が単一のアプリケーションで。
内容
1 歴史
1.1 実装の問題
2 標準の文字列タイプ
2.1 使用例 2.2 関連クラス 2.3 批評
3 参考文献
歴史
std ::文字列タイプは1998年以来、標準C ++の主な文字列データ型であるが、それは常にC ++の一部ではありませんでした。Cから、C ++は、最初の要素へのポインターによって処理されるnullで終了する文字列と、そのような文字列を操作する関数のライブラリを使用するという規則を継承しました。最新の標準C ++では、「hello」などの文字列リテラル
は、NULで終了する文字の配列を示します。
C ++クラスを使用して文字列型を実装すると、自動メモリ管理のいくつかの利点と、範囲外アクセスのリスクの低減、および文字列の比較と連結のためのより直感的な構文が提供されます。したがって、そのようなクラスを作成することは非常に魅力的でした。長年にわたり、C ++アプリケーション、ライブラリ、およびフレームワークの開発者は、AT&Tの標準コンポーネントライブラリ(最初の実装、1983)や
MicrosoftのMFCのCStringタイプなど、独自の互換性のない文字列表現を作成しました。間
のstd ::文字列のレガシーアプリケーションは、まだ一般的なカスタム文字列の種類とライブラリが含まれている標準化された文字列は、それが「事実上不可能」C ++プログラムでは、複数の文字列型を使用しないようになって、Cスタイルの文字列を期待して、とプログラマーを必要としますプロジェクトを開始する前に、目的の文字列表現を決定します。
C ++の歴史に関する1991年の回顧展で、その発明者であるBjarne Stroustrupは、C ++ 1.0に標準の文字列型(およびその他のいくつかの標準型)がないことを、開発で犯した最悪の間違いと呼びました。「それらの欠如は、誰もが車輪の再発明を行い、最も基本的なクラスで不必要な多様性をもたらしました」。
実装の問題
さまざまなベンダーの文字列タイプには、さまざまな実装戦略とパフォーマンス特性が特に、一部の文字列タイプは、コピーオンライト戦略を使用します。
string a = “hello!” ; 文字列 b = a ; //コンストラクタをコピーします
実際のコンテンツをコピーしない B ; 代わりに、両方の文字列がコンテンツを共有し、コンテンツの参照カウントが増加します。実際のコピーは、いずれかの文字列に文字を追加するなどの変更操作によって文字列の内容が異なるまで延期されます。コピーオンライトは、文字列を使用してコードのパフォーマンスを大幅に変更できます(一部の操作ははるかに高速になり、一部は非常に遅くなります)。けれども
のstd ::文字列は、もはやそれを使用して、多くの(おそらく最も)の代替文字列ライブラリは、まだコピー・オン・ライトの文字列を実装し
一部の文字列実装は、バイトではなく16ビットまたは32ビットのコードポイントを格納します。これは、Unicodeテキストの処理を容易にすることを目的としています。ただし、std :: stringまたはバイト配列からこれらのタイプへの変換は、「ロケール」に依存して、時間がかかり、多くの場合不可逆操作であり、例外をスローする可能性があることを意味し
ます。可変幅UTF-16エンコーディングが導入されたとき、16ビットコードユニットの処理上の利点はなくなりました(ただし、Windowsなどの16ビットAPIと通信する必要がある場合はまだ利点があります)。Qtの
QStringは一例です。
サードパーティの文字列の実装も、部分文字列を抽出または比較したり、テキスト内で検索を実行したりするための構文が大幅に異なりました。
標準の文字列タイプ
std ::文字列クラスは、以降のテキスト文字列のための標準的な表現であるC ++ 98。このクラスは、比較、連結、検索と置換、および部分文字列を取得するための関数など、いくつかの一般的な文字列操作を提供します。
std ::文字列は、 Cスタイルの文字列から構築することができ、Cスタイルの文字列も1から取得することができます。
文字列を構成する個々の単位はchar型
であり、少なくとも(ほとんどの場合)それぞれ8ビットです。最近の使用法では、これらは「文字」ではなく、UTF-8などのマルチバイト文字エンコーディングの一部であることがよく
コピーオンライト戦略は、std :: stringの最初のC ++標準で意図的に許可されていまし
た。これは、有用な最適化と見なされ、ほぼすべての実装で使用されていたためです。ただし、間違いがありました。特に、
演算子[]は、Cのインプレース文字列操作を簡単に移植できるようにするために、非定数参照を返しました(このようなコードは、多くの場合、文字ごとに1バイトを想定しているため、これにより、ほとんどの場合、文字列を調べるためだけに使用され、文字列を変更しない場合でも、コピーを作成する必要があることを示す次のコードが許可されました。
std :: string original (”aaaaaaa” ); std :: string string_copy = original ; //コピーを作成します char * ポインタ = &string_copy ; // operator []に「トリック」クラスを返させようとした人もいますが、これにより複雑になります 任意_code_here (); //これを修正できる最適化はありません * pointer = ‘b’ ; // operator []がコピーしなかった場合、これは予期せず元のファイルを変更します
これにより、いくつかの実装が発生しましたコピーオンライトを放棄します。また、参照カウントを調べたり変更したりするために必要なロックによるマルチスレッドアプリケーションのオーバーヘッドは、最新のプロセッサで小さな文字列をコピーするオーバーヘッドよりも大きいことがわかりました(特にポインタのサイズよりも小さい文字列の場合) )。最適化は、最終的に禁止されたC ++ 11、にも渡して、その結果
のstd ::文字列を関数の引数、すなわちとしては。
void print (std :: string s ) { std :: cout << s ; }
新しく割り当てられたメモリに文字列の完全なコピーを実行することが期待されている必要がこのようなコピーを回避するための一般的なイディオムは、const参照として渡すことです。
void print (const std :: string & s ) { std :: cout << s ; }
C ++ 17が新たな付加
string_viewのクラスをにのみポインタと長読み取り専用データであることを、上記実施例のいずれよりもはるかに高速の引数を渡すことができます。
void print (std :: string_view s ) { std :: cout << s ; } ... std :: string x = ...; 印刷(x ); // x.data()をコピーしません print ("これはリテラル文字列です" ); //文字もコピーしません!..。
使用例
#include #include int main (){ std :: string foo (”fighters” ); std ::文字列 バー(”スツール” ); if (foo != bar )
std :: cout << "文字列が異なります。" << std :: endl ; std :: cout << "String =" << bar << std :: endl ; 0を返す ; }
関連クラス
std :: stringは、std :: basic_stringテンプレートクラスの特定のインスタンス化のためのtypedefです
。その定義は
ヘッダーにあります:
typedef basic_string < char > string ;
したがって、
stringは、char型の要素を持つ文字列にbasic_string機能を
提供します
。そこ同様のクラスで
はstd :: wstringので構成され、
wchar_t型は、最も頻繁に格納するために使用されるUTF-16のテキストのWindowsおよびUTF-32ほとんどのUnixライクなプラットフォーム。ただし、C ++標準は、これらの型にUnicodeコードポイントまたはコードユニットとしての解釈を課すことはなく、wchar_tがcharよりも多くのビットを保持
することを保証するものでもありません
。 wchar_tのプロパティに起因する非互換性のいくつかを解決するために
、C ++ 11は2つの新しいクラスを追加しました:
std :: u16stringと
std :: u32string(新しいタイプ char16_tと char32_tで構成されています)。すべてのプラットフォームでのコード単位あたりのビット数。 C ++ 11は、16ビットおよび32ビットの「文字」の新しい文字列リテラルとUnicodeコードポイントをnullで終了する(Cスタイルの)文字列に入れるための構文も追加しました。
basic_stringを持つあらゆるタイプのspecializableであることが保証されて
char_traitsのそれを同行する構造体。C ++ 11以降、 char、 wchar_t、
char16_t、および
char32_tの特殊化のみを標準ライブラリに実装する必要がその他のタイプは実装によって定義されます。各スペシャライゼーションは標準ライブラリコンテナでもあるため、標準ライブラリアルゴリズムを文字列のコードユニットに適用できます。
批評
設計
のstd ::文字列がによってモノリシック設計の一例として掲げてきたハーブサッター起算C ++ 98、71のクラスに103個のメンバ関数のことをされている可能性が、切り離さ実装効率の損失なし。
参考文献
^ a b Seacord、Robert C.(2013)。CおよびC ++でのセキュアコーディング。アディソン-ウェスリー。ISBN 9780132981972。
^ Oualline、Steve(2003)。実用的なC ++プログラミング。オライリー。
^ a b Stroustrup、Bjarne(1993)。C ++の歴史:1979–1991(PDF)。手順 プログラミング言語会議のACMの歴史。
^ a b Solter、Nicholas A。; Kleper、Scott J.(2005)。プロフェッショナルC ++。ジョンワイリー&サンズ。p。23. ISBN
 9780764589492。
^ a b ブランシェット、ジャスミン; サマーフィールド、マーク(2008)。Qt4を使用したC ++ GUIプログラミング。ピアソンエデュケーション。ISBN
 9780132703000。
^ a b Meyers、Scott(2012)、Effective STL、Addison-Wesley、64〜65ページ、ISBN  9780132979184 ^ a b メレディス、アリスデア; ベーム、ハンス; クロウ、ローレンス; ディモフ、ピーター(2008)。「基本文字列の同時実行の変更」。ISO / IEC JTC 1 / SC 22 / WG21 。取得した19年11月2015。
^ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21334
^ サッター、ハーブ(1999)。「(マルチスレッドの世界では)そうではない最適化」。C / C ++ユーザージャーナル。17(6)。
^ “std :: basic_string_view –cppreference.com”。en.cppreference.com 。検索された23年6月2016。
^ 「basic_stringのC ++リファレンス」。Cppreference.com 。
^ Gillam、Richard(2003)。Unicodeの謎を解き明かす:エンコーディング標準の実用的なプログラマーズガイド。アディソン-ウェスリープロフェッショナル。p。714. ISBN
 9780201700527。
^ 「C ++ 11ペーパーN3336」。オープンスタンダード。プログラミング言語C ++、ライブラリワーキンググループ。2012年1月13日。
^ Stroustrup、Bjarne(2013)。C ++プログラミング言語。アディソンウェスリー。p。179. 2015年11月25日のオリジナルからアーカイブ。取得した24年11月2015。
^ “char_traits-C ++リファレンス” 。
^ サッター、ハーブ。”モノリス” Unstrung ” “。gotw.ca 。取得した23年11月2015。

投稿日:
カテゴリー: C