Строка представляет собой последовательность символов, поэтому объект типа string можно использовать как выражение в серийном операторе for. Например, серийный оператор for можно использовать для вывода каждого символа строки в отдельной строке вывода.

string str("some string");

// вывести символы строки str по одному на строку

for (auto с : str)  // для каждого символа в строке str

 cout << с << endl; // вывести текущий символ и символ новой строки

Цикл for ассоциирует переменную с с переменной str типа string. Управляющая переменная цикла определяется тем же способом, что и любая другая переменная. В данном случае используется спецификатор auto (см. раздел 2.5.2), чтобы позволить компилятору самостоятельно определять тип переменной с, которым в данном случае будет тип char. На каждой итерации следующий символ строки str будет скопирован в переменную с. Таким образом, можно прочитать этот цикл так: "Для каждого символа с в строке str" сделать нечто. Под "нечто" в данном случае подразумевается вывод текущего символа, сопровождаемого символом новой строки.

Рассмотрим более сложный пример и используем серийный оператор for, а также функцию ispunct() для подсчета количества знаков пунктуации в строке:

string s("Hello World!!!");

// punct_cnt имеет тот же тип, что и у возвращаемого значения

// функции s.size(); см. p. 2.5.3

decltype(s.size()) punct_cnt = 0;

// подсчитать количество знаков пунктуации в строке s

for (auto с : s) // для каждого символа в строке s

 if (ispunct(c)) // если символ знак пунктуации

   ++punct_cnt;  // увеличить счетчик пунктуаций

cout << punct_cnt

     << " punctuation characters in " << s << endl;

Вывод этой программы таков:

3 punctuation characters in Hello World!!!

Здесь для объявления счетчика punct_cnt используется спецификатор decltype (см. раздел 2.5.3). Его тип совпадает с типом возвращаемого значения функции s.size(), которым является тип string::size_type. Для обработки каждого символа в строке используем серийный оператор for. На сей раз проверяется, является ли каждый символ знаком пунктуации. Если да, то используем оператор инкремента (см. раздел 1.4.1) для добавления единицы к счетчику. Когда серийный оператор for завершает работу, отображается результат.

Использование серийного оператора for для изменения символов в строке

Если необходимо изменить значение символов в строке, переменную цикла следует определить как ссылочный тип (см. раздел 2.3.1). Помните, что ссылка — это только другое имя для данного объекта. При использовании ссылки в качестве управляющей переменной она будет по очереди связана с каждым элементом последовательности. Используя ссылку, можно изменить символ, с которым она связана.

Предположим, что вместо подсчета знаков пунктуации необходимо преобразовать все буквы строки в верхний регистр. Для этого можно использовать библиотечную функцию toupper(), которая возвращает полученный символ в верхнем регистре. Для преобразования всей строки необходимо вызвать функцию toupper() для каждого символа и записать результат в тот же символ:

string s("Hello World!!!");

// преобразовать s в верхний регистр

for (auto &с : s) // для каждого символа в строке s

                  // (примечание: с - ссылка)

 с = toupper(с);  // с - ссылка, поэтому присвоение изменяет

                  // символ в строке s

cout << s << endl;

Вывод этого кода таков:

HELLO WORLD!!!

На каждой итерации переменная с ссылается на следующий символ строки s. При присвоении значения переменной с изменяется соответствующий символ в строке s.

с = toupper(с); // с - ссылка, поэтому присвоение изменяет

                // символ в строке s

Таким образом, данное выражение изменяет значение символа, с которым связана переменная с. По завершении этого цикла все символы в строке str будут в верхнем регистре.

Обработка лишь некоторых символов
Перейти на страницу:

Похожие книги