|
Программирование >> Инициализация объектов класса, структура
#include <string> #include <iostream> int main() { string numerics( 0123456789 ); string name( r2d2 ); string:: size type pos = name.find first of( numerics ); cout << найдена цифра в позиции: << pos << \tэлемент равен pos << \tэлемент равен name[pos] << endl; В этом примере pos получает значение 1 (напоминаем, что символы строки нумеруются с Но нам нужно найти все вхождения символа, а не только первое. Такая возможность реализуется передачей функции find first of() второго параметра, указывающего позицию, с которой начать поиск. Изменим предыдущий пример. Можете ли вы сказать, #include <string> #include <iostream> int main() { string numerics( 0123456789 ); string name( r2d2 ); string::size type pos = 0; где-то здесь ошибка! while (( pos = name.find first of( numerics, pos )) != string::npos ) cout << найдена цифра в позиции: << pos << \tэлемент равен << name[pos] << endl; что в нем все еще не вполне удовлетворительно? В начале цикла pos равно 0, поэтому поиск идет с начала строки. Первое вхождение обнаружено в позиции 1. Поскольку найденное значение не совпадает с string::npos, выполнение цикла продолжается. Для второго вызова find first of() значение pos равно 1. Поиск начнется с 1-й позиции. Вот ошибка! Функция find first of() снова найдет цифру в первой позиции, и снова, и снова... Получился бесконечный цикл. Нам необходимо увеличивать pos на 1 в конце каждой итерации: исправленная версия цикла while (( pos = name.find first of( numerics, pos )) != string::npos ) cout << найдена цифра в позиции: << pos << \tэлемент равен << name[pos] << endl; сдвинуться на 1 символ ++pos; Чтобы найти все пустые символы (к которым, помимо пробела, относятся символы табуляции и перевода строки), нужно заменить строку numerics в этом примере строкой, содержащей все эти символы. Если же мы уверены, что используется только символ фрагмент программы while (( pos = textline.find first of( , pos )) != string::npos ) пробела и никаких других, то можем явно задать его в качестве параметра функции: ... фрагмент программы pos: позиция на 1 большая конца слова prev pos: позиция начала слова string::size type pos = 0, prev pos = 0; while (( pos = textline.find first of( , pos )) != string::npos ) ... запомнить позицию начала слова prev pos = ++pos; Чтобы узнать длину слова, введем еще одну переменную: На каждой итерации prev pos указывает позицию начала слова, а pos - позицию следующего символа после его конца. Соответственно, длина слова равна: pos - prev pos; длина слова После того как м1 выделили слово, необходимо поместить его в строков1й вектор. Это можно сделать, копируя в цикле символы из textline с позиции prev pos до pos -1. Функция substr() сделает это за нас: фрагмент программы vector<string> words; g> while (( pos = textline.find first of( , pos )) != string::npos ) words.push back( textline.substr( prev pos, pos-prev pos)); prev pos = ++pos; Функция substr() возвращает копию подстроки. Первый ее аргумент обозначает первую позицию, второй - длину подстроки. (Второй аргумент можно опустить, тогда подстрока включит в себя остаток исходной строки, начиная с указанной позиции.) В нашей реализации допущена ошибка: последнее слово не будет помещено в контейнер. Почему? Возьмем строку: i seaspawn and seawrack После каждого из первых двух слов поставлен пробел. Два вызова функции find first of() вернут позиции этих пробелов. Третий же вызов вернет string::npos, и цикл закончится. Таким образом, последнее слово останется необработанным. Вот полный текст функции, названной нами separate words() . Помимо сохранения слов в векторе строк, она вычисляет координаты каждого слова - номер строки и колонки (нам эта информация потребуется впоследствии).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |