Серийный оператор 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().