C ++文字列処理


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 :: string型は、1998年以降の標準C ++の
主要な文字列データ型ですが、常にC ++の一部であるとは限りませんでした。Cから、C ++は、最初の要素へのポインターによって処理されるnullで終了する文字列と、そのような文字列を操作する関数のライブラリを使用するという規則を継承しました。最新の標準C ++では、 「hello」などの文字列リテラル
は、NULで終了する文字の配列を示します。
C ++クラスを使用して文字列型を実装すると、自動メモリ管理のいくつかの利点と、範囲外アクセスのリスクの低減、および文字列の比較と連結のためのより直感的な構文が提供されます。したがって、そのようなクラスを作成することは非常に魅力的でした。長年にわたり、C ++アプリケーション、ライブラリ、およびフレームワークの開発者は、 AT&Tの標準コンポーネントライブラリ(最初の実装、1983)や
MicrosoftのMFCのCStringタイプなど、互換性のない独自の文字列表現を作成しました。 std :: stringの標準化された文字列ですが、レガシーアプリケーションには依然として一般的にそのようなカスタム文字列型が含まれて
おり、ライブラリはCスタイルの文字列を期待する可能性があるため、C ++プログラムで複数の文字列型を使用することを回避することは「事実上不可能」です。プロジェクトを開始する前に、目的の文字列表現を決定します。
C ++の歴史に関する1991年の回顧展で、その発明者であるBjarne Stroustrupは、C ++ 1.0に標準の文字列型(およびその他のいくつかの標準型)がないことを、開発で犯した最悪の間違いと呼びました。「それらの欠如は、誰もが車輪の再発明を行い、最も基本的なクラスで不必要な多様性をもたらしました」。

実装の問題
さまざまなベンダーの文字列タイプには、さまざまな実装戦略とパフォーマンス特性が特に、一部の文字列タイプは、コピーオンライト戦略を使用します。
string a = “hello!” ; 文字列b = a ; //コンストラクタをコピーします
実際にはaの内容を
bにコピーしません
。代わりに、両方の文字列がコンテンツを共有し、コンテンツの参照カウントが増加します。実際のコピーは、いずれかの文字列に文字を追加するなどの変更操作によって文字列の内容が異なるまで延期されます。コピーオンライトは、文字列を使用してコードのパフォーマンスを大幅に変更する可能性があります(一部の操作ははるかに高速になり、一部は非常に遅くなります)。std
:: stringはそれを使用しなくなりましたが、多くの(おそらくほとんどの)代替文字列ライブラリは依然としてコピーオンライト文字列を実装しています。
一部の文字列実装は、バイトではなく16ビットまたは32ビットのコードポイントを格納します。これは、 Unicodeテキストの処理を容易にすることを目的としています。ただし、 std :: stringまたはバイト配列からこれらのタイプへの変換
は、「ロケール」に依存して、低速で多くの場合不可逆操作であり、例外をスローする可能性があることを意味します。可変幅UTF-16エンコーディングが導入されたとき、16ビットコードユニットの処理上の利点はなくなりました(ただし、Windowsなどの16ビットAPIと通信する必要がある場合はまだ利点があります)。Qtの
QStringは一例です。
サードパーティの文字列の実装も、部分文字列を抽出または比較したり、テキスト内で検索を実行したりするための構文が大幅に異なりました。

標準の文字列型
std :: stringクラスは、C ++ 98以降のテキスト文字列の
標準表現です。このクラスは、比較、連結、検索と置換、および部分文字列を取得するための関数など、いくつかの一般的な文字列操作を提供します。std :: stringはCスタイルの文字列から作成でき、Cスタイルの文字列も1つから取得できます。
文字列を構成する個々のユニットはchar型
であり、少なくとも(ほとんどの場合)それぞれ8ビットです。最近の使用法では、これらは「文字」ではなく、UTF-8などのマルチバイト文字エンコーディングの一部であることがよく
コピーオンライト戦略は、std :: stringの初期のC ++標準によって意図的に許可されまし
た。これは、有用な最適化と見なされ、ほぼすべての実装で使用されたためです。ただし、間違いがありました。特に、
演算子[]は、Cのインプレース文字列操作を簡単に移植できるようにするために、非定数参照を返しました(このようなコードは、多くの場合、文字ごとに1バイトを想定しているため、これにより、文字列を調べるためだけに使用され、文字列を変更しない場合でも、コピーを作成する必要があることを示す次のコードが可能になりました。
std :: string original (”aaaaaaa” ); std :: string string_copy = original ; //コピーを作成しますchar * pointer = &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 #include <文字列> int main (){
std :: string foo = “fighters” ;
std :: string bar = “stool” ;
if (foo != bar )std :: cout << "文字列が異なります! n " ;
std :: cout << "foo =" << std :: quoted (foo )
<< "while bar =" << std :: quoted (bar ); }

関連クラス
std :: stringは、std :: basic_stringテンプレートクラスの特定のインスタンス化のためのtypedefです
。その定義は
ヘッダーにあります:
string = std :: basic_string < char > ;を使用します。
したがって、
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の時点では、har、 char_t、
char16_t、および
char32_tの特殊化のみを標準ライブラリに実装する必要がその他のタイプは実装定義です。各特殊化は標準ライブラリコンテナでもあるため、標準ライブラリアルゴリズムを文字列のコードユニットに適用できます。

批評
設計
のstd ::文字列がによってモノリシック設計の一例として掲げてきたハーブサッター起算C ++ 98、71のクラスに103個のメンバ関数のことをされている可能性が、切り離さ実装効率の損失なし。

参考文献
^ Seacord、Robert C.(2013)。CおよびC ++でのセキュアコーディング。アディソン-ウェスリー。ISBN 9780132981972。
^ Oualline、Steve(2003)。実用的なC ++プログラミング。オライリー。
^ Stroustrup、Bjarne(1993)。C ++の歴史:1979–1991(PDF)。Proc。プログラミング言語会議のACMの歴史。
^ ソルター、ニコラスA。; Kleper、Scott J.(2005)。プロフェッショナルC ++。ジョン・ワイリー&サンズ。p。23. ISBN
 9780764589492。
^ ブランシェット、ジャスミン; サマーフィールド、マーク(2008)。Qt4を使用したC ++ GUIプログラミング。ピアソン教育。ISBN
 9780132703000。
^ Meyers、Scott(2012)、Effective STL、Addison-Wesley、64〜65ページ、ISBN  9780132979184 ^ メレディス、アリスデア; ベーム、ハンス; クロウ、ローレンス; ディモフ、ピーター(2008)。「基本文字列への同時実行の変更」。ISO / IEC JTC 1 / SC 22 / WG21 。
^ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21334
^ サッター、ハーブ(1999)。「(マルチスレッドの世界では)ない最適化」。C / C ++ユーザージャーナル。17(6)。
^ “std :: basic_string_view –cppreference.com”。en.cppreference.com 。
^ 「basic_stringのC ++リファレンス」。Cppreference.com 。
^ Gillam、Richard(2003)。Unicodeの謎を解き明かす:エンコーディング標準の実用的なプログラマーガイド。アディソン-ウェスリープロフェッショナル。p。714. ISBN
 9780201700527。
^ 「C ++ 11ペーパーN3336」。オープンスタンダード。プログラミング言語C ++、ライブラリワーキンググループ。
^ Stroustrup、Bjarne(2013)。C ++プログラミング言語。アディソンウェスリー。p。179.
^ “char_traits-C ++リファレンス” 。
^ サッター、ハーブ。”モノリス” Unstrung ” “。gotw.ca 。