C++. Сборник рецептов - [70]

Шрифт
Интервал

чем такое:

>if ((s1.size() == s2.size()) &&

>std::equal(s1.begin(), s1.end(s2.begin(), caseInsCharCompare)) {

> // они равны, делаем что-нибудь

когда требуется выполнить сравнение строк без учета регистра.

4.14. Выполнение поиска строк без учета регистра

Проблема

Требуется найти в строке подстроку, не учитывая разницу в регистре.

Решение

Используйте стандартные алгоритмы >transform и >search, определенные в >, а также свои собственные функции сравнения символов, аналогичные уже показанным. Пример 4.22 показывает, как это делается.

Пример 4.22. Поиск строк без учета регистра

>#include

>#include

>#include

>#include

>#include


>using namespace std;


>inline bool caseInsCharCompSingle(char a. char b) {

> return(toupper(a) == b);

>}


>string::const_iterator caseInsFind(string& s, const string& p) {

> string tmp;

> transform(p.begin( ), p.end(), // Преобразуем шаблон

>  back_inserter(tmp),           // к верхнему регистру

>  toupper);

> return(search(s.begin(), s.end(), // Возвращаем итератор.

>  tmp.begin(), tmp.end(),          // возвращаемый из

>  caseInsCharCompSingle));         // search

>}


>int main() {

> string s = "row, row, row, your boat";

> string p = "YOUR";

> string::const_iterator ir = caseInsFind(s, p);

> if (it != s.end()) {

>  cout << "Нашли!\n;

> }

>}

Возвращая итератор, который указывает на элемент целевой строки, где начинается шаблонная строка, мы обеспечиваем совместимость с другими стандартными алгоритмами, так как большинство из них принимают в качестве аргумента итератор.

Обсуждение

Пример 4.22 демонстрирует обычный ход действий при работе со стандартными алгоритмами. Создайте функцию, которая выполняет работу, а затем подключите ее как объект функции к наиболее подходящему алгоритму. Здесь работу выполняет функция >charInsCharCompSingle, но в отличие от примера 4.21 эта функция сравнения символов переводит к верхнему регистру только первый аргумент. Это сделано потому, что немного далее в >caseInsFind я перед использованием строки шаблона в поиске преобразую ее к верхнему регистру полностью и тем самым избегаю многократного преобразования символов строки шаблона к верхнему регистру.

После того как функция сравнения будет готова, используйте для поиска стандартные алгоритмы >transform и >search. >transform используется для преобразования к верхнему регистру всего шаблона (но не целевой строки). После этого используйте для поиска места вхождения подстроки search совместно с функцией сравнения.

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

В примере 4.22 есть одна вещь, которая выглядит странно. Вы видите, что >caseInsCompare возвращает >const_iterator, как в

>string::const_iterator caseInsFind(const string& s,

> const string& p)

Что, если требуется изменить элемент, на который указывает возвращенный итератор? Тому есть причина. Она состоит в том, что константный итератор используется потому, что строки, которые передаются в >caseInsFind, также передаются как >const, и, следовательно, невозможно получить не->const итератор на >const-строку. Если требуется итератор, который можно использовать для изменения строки, удалите >const из параметров и измените объявление функции так, чтобы она возвращала >string::iterator.

4.15. Преобразование между табуляциями и пробелами в текстовых файлах

Проблема

Имеется текстовый файл, содержащий табуляции или пробелы, и требуется преобразовать одни в другие. Например, может потребоваться заменить все табуляции на последовательности из трех пробелов или сделать наоборот и заменить все вхождения некоторого числа пробелов на табуляции.

Решение

Независимо от того, производится ли замена табуляций на пробелы или пробелов на табуляции, используйте классы >ifstream и >ofstream из >. В первом (более простом) случае прочтите данные по одному символу с помощью входного потока, изучите их и, если очередной символ — это табуляция, запишите в выходной поток некоторое количество пробелов. Пример 4.23 демонстрирует, как это делается.

Пример 4.23. Замена табуляций на пробелы

>#include

>#include

>#include


>using namespace std;


>int main(int argc, char** argv) {

> if (argc < 3)

>  return(EXIT_FAILURE);

> ifstream in(argv[1]);

> ofstream out(argv[2]);

> if (!in || !out) return(EXIT_FAILURE);

> char c;

> while (in.get(c)) {

>  if (c == '\t')

>   out << " "; // 3 пробела

>  else

>   out << c;

> }

> out.close();

> if (out)

>  return(EXIT_SUCCESS);

> else

>  return(EXIT_FAILURE);

>}

Если же требуется заменить пробелы на табуляции, обратитесь к примеру 4.24. Он содержит функцию >spacesToTabs, которая читает из входного потока по одному символу, ища три последовательных пробела. Когда они найдены, она записывает в выходной поток табуляцию. Для всех остальных символов или меньшего количества пробелов в выходной поток записывается то, что было прочитано во входном.


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.