Читать интересную книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 245 246 247 248 249 250 251 252 253 ... 337
!= boys)

        error("Количество мальчиков не сходитсяn");

      if (curr_girl != girls)

        error("Количество девочек не сходитсяn");

      if (!(in>>ws).eof())

        error("Символы после итоговой строки");

      return 0;

    }

    // обновляем суммы:

    boys += curr_boy;

    girls += curr_girl;

  }

    error("Итоговой строки нет");

}

Последняя строка по смыслу отличается от остальных: в ней содержатся суммы. Мы распознаем ее по метке (“Alle klasser”). Мы решили, что после последнего символа не должны стоять символы, не являющиеся разделителями (для распознавания этого факта используется функция lexical_cast() (см. раздел 23.2)), и выдаем сообщение об ошибке в случае их обнаружения.

Для того чтобы извлечь числа из полей данных, мы использовали функцию from_string() из раздела 23.2. Мы уже проверили, что эти поля содержат только цифры, поэтому проверять правильность преобразования объекта класса string в переменную типа int не обязательно.

23.10. Ссылки

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

Перечислим некоторые из этих источников.

Aho, Alfred V., Monica S. Lam, Ravi Sethi, and Jeffrey D. Ullman. Compilers: Principles, Techniques, and Tools, Second Edition (обычно называемая “The Dragon Book”). Addison-Wesley, 2007. ISBN 0321547985.

Austern, Matt, ed. “Draft Technical Report on C++ Library Extensions”. ISO/IEC DTR 19768, 2005. www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n2336.pdf.

Boost.org. Хранилище библиотек, согласованных со стандартной библиотекой языка С++. www.boost.org.

Cox, Russ. “Regular Expression Matching Can Be Simple and Fast (but Is Slow in Java, Perl, PHP, Python, Ruby, ...)”. http://swtch.com/~rsc/regexp/regexp1.html.

Maddoc, J. boost::regex documentation. www.boost.org/libs/regex/doc/index.html.

Schwartz, Randal L., Tom Phoenix, and Brian D. Foy. Learning Perl, Fourth Edition.

O’Reilly, 2005. ISBN 0596101058.

Задание

1. Выясните, является ли библиотека regex частью вашей стандартной библиотеки. Подсказка: ищите std::regex и tr1::regex.

2. Запустите небольшую программу из раздела 23.7; для этого может понадобиться инсталлировать библиотеку boost::regex на вашем компьютере (если вы этого еще не сделали) и настроить опции проекта или командной строки для установления связи с библиотекой regex, а затем использовать заголовки regex.

3. Используйте программу из задания 2 для проверки шаблонов из раздела 23.7.

Контрольные вопросы

1. Где мы находим “text”?

2. Какие возможности стандартной библиотеки чаще всего используются для анализа текста?

3. Куда вставляет элемент функция insert() — перед или после указанной позиции (или итератора)?

4. Что такое Unicode?

5. Как конвертировать тип в класс string и наоборот?

6. В чем заключается разница между инструкцией cin>>s и вызовом функции getline(cin,s), если s — это объект класса string?

7. Перечислите стандартные потоки.

8. Что собой представляет ключ ассоциативного массива map? Приведите примеры полезных типов для ключей.

9. Как перемещаться по элементам контейнера класса map?

10. В чем заключается разница между классами map и multimap? Какой полезной операции, существующей в классе map, нет в классе multimap и почему?

11. Какие операции требуются для однонаправленного итератора?

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

13. Зачем нужен символ управляющей последовательности при формировании регулярных выражений?

14. Как превратить регулярное выражение в переменную типа regex?

15. Какие строки соответствуют шаблону w+sd{4}? Приведите три примера. Какой строковый литерал нужно использовать для инициализации переменной типа regex заданным шаблоном?

16. Как (в программе) выяснить, является ли строка корректным регулярным выражением?

17. Что делает функция regex_search()?

18. Что делает функция regex_match()?

19. Как представить символ точки (.) в регулярном выражении?

20. Как выразить понятие “не меньше трех” в регулярном выражении?

21. Относится ли символ 7 к группе w? А символ _ (подчеркивания)?

22. Какое обозначение используется для символов в верхнем регистре?

23. Как задать свой собственный набор символов?

24. Как извлечь значение из целочисленного поля?

25. Как представить число с плавающей точкой с помощью регулярного выражения?

26. Как извлечь число с плавающей точкой из строки, соответствующей шаблону?

27. Что такое частичное совпадение (sub-match)? Как его обнаружить?

Термины

Упражнения

1. Запустите программу, работающую с файлом сообщений электронной почты; протестируйте ее, используя свой собственный, более длинный файл. Убедитесь, что в этом файле есть сообщения, вызывающие сообщения об ошибках, например, сообщения с двумя адресными строками, несколько сообщений с одинаковыми адресами и/или темами и пустые сообщения. Кроме того, протестируйте программу на примере, который вообще не является сообщением и не соответствует программной спецификации, например, на файле, не содержащем строк ----.

2. Добавьте класс multimap и поместите в него темы сообщений. Пусть программа вводит строки с клавиатуры и выводит каждое сообщение, у которого тема совпадает с заданной строкой.

3. Модифицируйте пример из раздела 23.4 и примените регулярные выражения для выявления темы и отправителя сообщения электронной почты.

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

5. Найдите большой файл с сообщениями электронной почты (тысячи сообщений), а затем запишите его в объекты класса multimap и unordered_multimap. Обратите внимание на то, что в нашем приложении никак не используется преимущество упорядоченности объекта класса multimap.

6. Напишите программу, обнаруживающую даты в текстовом файле. Выведите на печать каждую строку, содержащую хотя бы одну дату в формате linenumber:line. Начните с регулярного выражения для простого формата, например 12/24/2000, и протестируйте ее на нем. Затем добавьте новые форматы.

7. Напишите программу (аналогичную предыдущей), которая находит номера кредитных карточек в файле. Разберитесь в том, какие форматы на самом деле используются для записи номеров кредитных карточек, и реализуйте их проверку в вашей программе.

8. Модифицируйте программу из раздела 23.8.7 так, чтобы на ее вход поступали шаблон и имя файла. Результатом работы программы должны быть

1 ... 245 246 247 248 249 250 251 252 253 ... 337
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп.
Книги, аналогичгные Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Оставить комментарий