目次
はじめに
C++のstd::stringは、内部的には文字のコンテナであり、std::vectorなどと同様に、その要素(個々の文字)にアクセスするためのイテレータを提供します。イテレータは、文字列内の特定の位置を指し示す、ポインタのように振る舞うオブジェクトです。
forループで1文字ずつ処理したり、<algorithm>ライブラリの各種関数(sort, findなど)に文字列を渡したりする際に、このイテレータが重要な役割を果たします。
この記事では、stringのイテレータの基本的な使い方と、読み取り専用のconst_iteratorとの違いについて解説します。
stringイテレータを使ったサンプルコード
このコードは、stringのイテレータを取得し、それを使って文字列の最初の文字を変更する方法と、リバースイテレータを使って文字列を逆順にする方法を示します。
完成コード
#include <iostream>
#include <string>
#include <algorithm> // for_each
using namespace std;
// 1. 通常のイテレータ (読み書き可能)
void modify_first_char(string::iterator it_begin) {
*it_begin = 'X'; // 間接参照して、指し示す先の文字を変更
}
// 2. constイテレータ (読み取り専用)
void print_first_char(string::const_iterator cit_begin) {
cout << "最初の文字 (const): " << *cit_begin << endl;
// *cit_begin = 'Y'; // コンパイルエラー! constイテレータは変更不可
}
int main() {
string text = "hello";
cout << "元の文字列: " << text << endl;
// --- 読み書き可能なイテレータ ---
// .begin()は、読み書き可能な iterator を返す
modify_first_char(text.begin());
cout << "変更後の文字列: " << text << endl;
// --- 読み取り専用のイテレータ ---
// .cbegin()は、読み取り専用の const_iterator を返す
print_first_char(text.cbegin());
// --- リバースイテレータ ---
// .rbegin() / .rend() を使って、逆順の文字列を生成
string reversed_text(text.rbegin(), text.rend());
cout << "逆順にした文字列: " << reversed_text << endl;
return 0;
}
コードの解説
1. イテレータの種類と取得方法
std::stringは、主に以下のメンバ関数でイテレータを取得します。
| イテレータの種類 | 取得メンバ関数 | 説明 |
iterator | .begin(), .end() | 読み書き可能な、順方向のイテレータ |
const_iterator | .cbegin(), .cend() | 読み取り専用の、順方向のイテレータ |
reverse_iterator | .rbegin(), .rend() | 読み書き可能な、逆方向のイテレータ |
const_reverse_iterator | .crbegin(), .crend() | 読み取り専用の、逆方向のイテレータ |
iterator vs const_iterator
iterator:*it = 'X';のように、間接参照 (*) を使って、イテレータが指し示している先の文字を変更できます。const_iterator:constが付いている通り、指し示している先の文字を変更することはできません。読み取り専用の関数に文字列を渡す際に、意図しない変更を防ぐために使われ、より安全なコードになります。
rbegin() と rend()
.rbegin(): 文字列の末尾を指すリバースイテレータを返します。.rend(): 文字列の先頭の一つ前を指すリバースイテレータを返します。string reversed_text(text.rbegin(), text.rend());のように、stringの範囲コンストラクタに渡すことで、簡単に逆順の文字列を生成できます。
まとめ
今回は、std::stringをイテレータを使って操作する基本的な方法を解説しました。
stringは、他のSTLコンテナと同様にイテレータを持つ。.begin()は読み書き可能な**iteratorを、.cbegin()は読み取り専用のconst_iterator**を返す。.rbegin()を使えば、文字列を逆方向から処理できる。
イテレータを理解することで、<algorithm>ライブラリの豊富な関数群(find, sort, transformなど)をstd::stringに対してもシームレスに利用できるようになり、文字列操作の幅が大きく広がります。
