Телефонодобывающий комбайн Tony (tony@MadTanks.com) Спецвыпуск: Хакер, номер #056, стр. 056-060-3 Программа CellFinder Когда я начинал работу над этой программой, я четко представлял себе, что номер телефона может быть записан в любом виде и любом формате. Кроме того, задуманная мной программа должна была уметь работать с текстовыми и бинарными файлами произвольной длины. Понятно, что невозможно объять необъятное. Но можно разработать средство, легко позволяющее модифицировать себя и добавлять новую функциональность. В нашем случае это возможность добавлять новые фильтры, которые способны анализировать такие записи номеров, которые я не учел. Такая задача элегантно решается с помощью паттерна "Стратегия", который позволяет легко определять и использовать различные схемы поведения объектов [3]. Абстрактный класс iFilter определяет интерфейс фильтров телефонных номеров. Любой фильтр должен реализовывать этот интерфейс. Пока реализовано два фильтра, которые ищут номера, записанные в международном и федеральном формате в текстовом виде, то есть записаны коды символов цифр. Фильтры реализованы в классах cFederalNumberFilter и cInternationalNumberFilter. На вход фильтрам подается содержимое файла в виде массива байт: vector<char>. На выходе получается несортированный список найденных номеров. Работой программы управляет класс cFinder, который отвечает ЗА: - инстанцирование фильтров; - итерирование по всем файлам в указанном каталоге и его подкаталогах; - загрузку файлов в память; - обработку этих данных фильтрами и вторичную фильтрацию. Под вторичной фильтрацией понимается отбрасывание нестандартных и междугородних телефонных номеров, сортировка массива, отбрасывание повторяющихся номеров. Если тебе хочется добавить свой собственный фильтр, то необходимо сделать следующие телодвижения: создать класс, реализующий интерфейс iFilter, и зарегистрировать этот класс в менеджере cFinder так, как это сделано в листинге "Регистрация фильтров". Изменить процесс вторичной фильтрации телефонов можно с помощью метода cFinder::PostFilter(). На входе эта функция принимает только что найденный список телефонов, из этого списка она вырезает телефоны, количество цифр в которых отлично от 11. Кроме того, она записывает все номера в международном формате (с использованием ключевых символов "+7"). После этого вызывается метод cFinder::CheckOperatorCode(), который проверяет три цифры после ключевых символов, и если они не являются кодом оператора, номер игнорируется. Правда, здесь я немного поленился и посчитал, что коды всех операторов начинаются с девятки, но ты можешь проверить все три цифры на их соответствие кодам операторов нашей необъятной. Подводные камни На нашем диске ты можешь найти две версии исходных кодов программы (CellFinder, другая CellFinder STLPort). Они отличаются друг от друга лишь совместимостью с различными реализациями STL. Первая программа нормально компилируется любым компилятором языка C++ на платформе Win32. Вторая также компилируется любым компилятором, но не с любой реализацией STL. Штатная реализация STL MSVC++ 6.0 наотрез отказалась компилироваться с этим кодом, пришлось подставить STLPort (www.stlport.org). Все дело в итераторах буферизованного ввода, при помощи которых я читаю файлы. Подробнее эта тема рассмотрена в [2] (Совет 29). Не забудь, чтобы у тебя использовался не штатный STL. Необходимо указать его путь в настройках компилятора перед путем к штатному (см. на рис. "Настройки компилятора"). |