## 12.2 string 演算

以降の節で、string の作成と操作に使用される標準 C++ ライブラリの演算を説明します。

### 12.2.1 string の宣言と初期化

string の最も単純な宣言書式では、新規に変数が指定されるか、または string の初期値とともに変数が指定されます。この書式は、9.3.2 節のグラフプログラム例で広範に使用されました。コピーコンストラクタを使用して、 string が事前に定義された string から値を取り出すように宣言することもできます。

    string s1;
    string s2 ("a string");
    string s3 = "initial value";
    string s4 (s3);

この単純な例では、容量は格納される文字数と最初は正確に一致しています。代替コンストラクタを使用して容量を設定し、単一文字値を繰り返しコピーして string を初期化することができます。

    string s7 (10, '\n');          // 10 の改行文字を含む

最後に、標準 C++ ライブラリのすべてのコンテナクラスと同様に、1 対の iterator7 を使用して、string を初期化することができます。iterator によって示されるシーケンスには、適切な要素の型が定義されている必要があります。

    string s8 (aList.begin(), aList.end());

### 12.2.2 サイズと容量のリセット

vector データ型の場合と同様に、string の現在のサイズは `size()` メンバー関数によって得ることができます。また、現在の容量は `capacity()` によって返されます。現在の容量は、`reserve()` メンバー関数を呼び出すことによって変更することができます。この関数は、少なくとも引数によって指定された要素が文字列に包含されるように、必要に応じて容量を調整します。メンバー関数 `max_size()` は、割り当て可能な最大文字列サイズを返します。

    cout << s6.size() << endl;
    cout << s6.capacity() << endl;
    s6.reserve(200);                    // 容量を 200 に変更
    cout << s6.capacity() << endl;
    cout << s6.max_size() << endl;

メンバー関数 `length()` は、`size()` とよく似た関数です。メンバー関数 `resize()` は、文字を末端から切り捨てるか、新しい文字を挿入して、文字列のサイズを変更します。`resize()` の任意の 2 番目の引数を使用して、新規に作成される文字位置に挿入する文字を指定することができます。

    s7.resize(15, '\t');                // 後ろにタブ文字を追加
    cout << s7.length() << endl;        // これでサイズは 15 になる

メンバー関数 `empty()` は、文字列に文字が含まれない場合は `true` を返し、一般にゼロ定数となるような長さのテストよりも高速です。

    if (s7.empty())
       cout << "string is empty" << endl;

### 12.2.3 代入、追加、交換

文字列変数には、別の文字列、リテラルの C 形式文字配列、単一文字のいずれかの値を代入することができます。

    s1 = s2;
    s2 = "a new value";
    s3 = 'x';

これらの 3 つの書式の引数に演算子 `+=` を使用して、右側の値が現在の文字列値の末端に追加されるように指定することもできます。

    s3 += "yz";                   // s3 は xyz となる

より一般的なメンバー関数 `assign()` および `append()` を使用して、右側のサブセットを受け手に代入、または追加することができます。2 つの引数 `pos` および `n` は、位置 `pos` の後に `n` 個の値が代入、または追加されることを示します。

    s4.assign (s2, 0, 3);        // 最初の 3 文字を代入
    s4.append (s5, 2, 3);        // 文字 2、3 、4 を追加

加算演算子 `+` は、2 つの文字列連結を形成するために使用されます。演算子 `+` は、左の引数をコピーし、次に右の引数をこの値に追加します。

    cout << (s2 + s3) << endl;   // s2 と s3 の出力連結

標準 C++ ライブラリのすべてのコンテナと同様に、2 つの string の内容は `swap()` メンバー関数を使用して交換することができます。

    s5.swap (s4);                // s4 と s5 を交換

### 12.2.4 文字へのアクセス

文字列の個々の文字は、添字演算子を使用してアクセスまたは代入することができます。メンバー関数 `at()` は、要求された位置が `size()` に等しいか大きい場合に `out_of_range` 例外となることを除いて、ほぼこの操作と同義です。

    cout << s4[2] << endl;        // s4 の位置 2 を出力
    s4[2] = 'x';                  // 位置 2 の変更
    cout << s4.at(2) << endl;     // 更新された値を出力

メンバー関数 `c_str()` は、string に含まれる要素と同じ要素を持つ、NULL で終わる文字配列へのポインタを返します。この関数により、string を従来の C 形式文字配列へのポインタを要求する関数と共に使用することができます。結果のポインタは定数として宣言されます。これは、`c_str()` を使用して文字列を変更できないことを意味します。また、`c_str()` によって返される値は、`append()` や `insert()` などの再割り当てを要求する演算の後では、無効となる場合があります。メンバー関数 `data()` は、配下の文字バッファーにポインタを返します。

    char d[256];
    strcpy(d, s4.c_str());                // s4 を配列 d にコピー

### 12.2.5 反復子

メンバー関数 `begin()` および `end()` は、文字列の最初と最後のランダムアクセス iterator を返します。iterator によって示される値は、個々の文字列要素です。関数 `rbegin()` および `rend()` は、逆方向 iterator を返します。

### 12.2.6 挿入、削除、置換

string メンバー関数 `insert()` および `erase()` は、vector 関数 `insert()` および `erase()` と似ています。vector と同様に、引数に iterator を使用して、引数によって指定される範囲を挿入または削除します。関数 `replace()` は、削除と挿入を組み合わせたものであり、指定された範囲を新しい値に置き換えます。

    s2.insert(s2.begin()+2, aList.begin(), aList.end());
    s2.erase(s2.begin()+3, s2.begin()+5);
    s2.replace(s2.begin()+3, s2.begin()+6, s3.begin(), s3.end());

> 注 : 反復子の内容は、追加や挿入などの、内部文字列バッファーの再割り当てを引き起こす演算の後も有効であるという保証はないので注意してください。

上記の関数には、反復子を使用しない実装もあります。`insert()` メンバー関数は、引数に位置と string を使用して、string を指定の位置に挿入します。erase 関数は、位置と長さの 2 つの整数引数を使用し、指定された文字を消去します。replace 関数は、同様の 2 つの整数引数のほかに、文字列と任意の長さを使用して、指定された範囲を文字列と置き換えるか、長さが明示的に指定されている場合は文字列の最初の部分と置き換えます。

    s3.insert (3, "abc");      // 位置 3 の後に abc を挿入する
    s3.erase (4, 2);           // 位置 4 と 5 を削除する
    s3.replace (4, 2, "pqr");  // 位置 4 と 5 を pqr と置換える

### 12.2.7 コピーと部分文字列

メンバー関数 `copy()` は、部分文字列を生成して、最初の引数として渡される `char*` ターゲットにこの部分文字列を代入します。部分文字列の値の範囲は初期位置、または位置と長さによって指定されます。

    s3.copy (s4, 2);       // s3 の位置 2 から終わりまでを s4 に代入
    s5.copy (s4, 2, 3);    // s5 の位置 2 から 4 までを s4 に代入

メンバー関数 `substr()` は、現在の string の一部を表す string を返します。その範囲は初期位置、または位置と長さによって指定されます。

    cout << s4.substr(3) << endl;       // 3 から終わりまでを出力
    cout << s4.substr(3, 2) << endl;    // 位置 3 と 4 を出力

### 12.2.8 string の比較

メンバー関数 `compare()` は、受け手と引数文字列間の字句の比較に使用されます。任意の引数によって、異なる開始位置、すなわち引数文字列の開始位置と長さを指定することができます。字句の大小順序については、13.6.5 節を参照してください。これに従い、受け手が引数より小さい場合は、この関数は負の値を返し、等しい場合はゼロを返し、受け手が引数より大きい場合はプラス値を返します。

関係演算子および等価演算子 `<`、`<=`、`==`、`!=`、`>=`、`>` はすべて、比較メンバー関数を使用して定義されます。比較は 2 つの文字列間でも、文字列と通常の C 形式文字リテラル間でも行われます。

`compare()` の機能を説明しましたが、ユーザーがこのメンバー関数を直接呼び出すことはほとんどありません。実際には文字列の比較には従来の比較演算子が使用され、次にこの比較演算子が関数 `compare()` を使用して実行されるのが普通です。

### 12.2.9 検索操作

メンバー関数 `find()` は、現在の文字列内での最初の引数文字列が発生したことを検出します。任意の整数引数によって、検索の開始位置を指定することができます (文字列のインデックス位置はゼロで始まることに注意してください)。関数はこうした一致を検出すると、現在の文字列内の一致の開始インデックスを返します。検出できない場合は、文字列の正当な添字セットの範囲外の値を返します。関数 `rfind()` も同様ですが、文字列を終わりから走査し、逆方向に移動します。

    s1 = "mississippi";
    cout << s1.find("ss") << endl;              // 2 を返す
    cout << s1.find("ss", 3) << endl;           // 5 を返す
    cout << s1.rfind("ss") << endl;             // 5 を返す
    cout << s1.rfind("ss", 4) << endl;          // 2 を返す

関数 `find_first_of()`、`find_last_of()`、`find_first_not_of()`、`find_last_not_of()` は、引数文字列を文字のセットとして扱います。他の多くの関数と同様に、1 つまたは 2 つの任意の整数引数を使用して、現在の文字列のサブセットを指定することができます。これらの関数は、引数セットに含まれる文字、または含まれない文字の最初または最後の発生を検出します。指定した文字が検出されると、その位置が返されます。こうした文字が存在しない場合は、正当な添字の範囲外の値が返されます。

    i = s2.find_first_of ("aeiou");            // 最初の母音字を検索
    j = s2.find_first_not_of ("aeiou", i);     // 次の非母音字を検索

Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。
OEM リリース, 1998 年 6 月