Серийный оператор for
работает хорошо, когда необходимо обработать каждый символ. Но иногда необходим доступ только к одному символу или к некоторому количеству символов на основании некоего условия. Например, можно преобразовать в верхний регистр только первый символ строки или только первое слово в строке.
Существуют два способа доступа к отдельным символам в строке: можно использовать индексирование или итератор. Более подробная информация об итераторах приведена в разделе 3.4 и в главе 9.
[]
) получает значение типа string::size_type
(раздел 3.2.2), обозначающее позицию символа, к которому необходим доступ. Оператор возвращает ссылку на символ в указанной позиции.
Индексация строк начинается с нуля; если строка s
содержит по крайней мере два символа, то первым будет символ s[0]
, вторым — s[1]
, а последним символом является s[s.size() - 1]
.
>= 0
и < size()
). Результат использования индекса вне этого диапазона непредсказуем. Непредсказуема также индексация пустой строки.
Значение оператора индексирования называется size_type
(см. раздел 2.1.2).
Следующий пример использует оператор индексирования для вывода первого символа строки:
if (!s.empty()) //
cout << s[0] << endl; //
Прежде чем обратиться к символу, удостоверимся, что строка s
не пуста. При каждом использовании индексирования следует проверять наличие значения в данной области. Если строка s
пуста, то значение s[0]
неопределенно.
Если строка не константа (см. раздел 2.4), возвращенному оператором индексирования символу можно присвоить новое значение. Например, первый символ можно перевести в верхний регистр следующим образом:
string s("some string");
if (!s.empty()) //
s[0] = toupper(s[0]); //
Вывод этой программы приведен ниже.
Some string
В следующем примере переведем в верхний регистр первое слово строки s
:
//
//
for (decltype(s.size()) index = 0;
index != s.size() && !isspace(s[index]); ++index)
s[index] = toupper(s[index]); //
Вывод этой программы таков:
SOME string
Цикл for
(см. раздел 1.4.2) использует переменную index
для индексирования строки s
. Для присвоения переменной index
соответствующего типа используется спецификатор decltype
. Переменную index
инициализируем значением 0
, чтобы первая итерация началась с первого символа строки s
. На каждой итерации значение переменной index
увеличивается, чтобы получить следующий символ строки s
. В теле цикла текущий символ переводится в верхний регистр.
В условии цикла for
используется новая часть — &&
). Этот оператор возвращает значение true
, если оба операнда истинны, и значение false
в противном случае. Важно то, что этот оператор гарантирует обработку своего правого операнда, s
не будет, если переменная index
находится вне диапазона. Таким образом, часть s[index]
выполняется, только если переменная index
не равна s.size()
. Поскольку инкремент переменной index
никогда не превзойдет значения s.size()
, переменная index
всегда будет меньше s.size()
.