|
Программирование >> Разработка устойчивых систем
strings stripHTMLTags(strings s) { static bool inTag = false: bool done = false: while (!done) { if (inTag) { В предыдущей строке начался, но не закончился тег HTML. Продолжаем поиск >. size t rightPos = s.find(>): if (rightPos != string::npos) { inTag = false: s.erase(0. rightPos + 1): else { done = true: s.eraseO: else { Поиск начала тега: size t leftPos = s.find(<): if (leftPos != string::npos) { Проверить, закрывается ли тег в текущей строке size t rightPos = s.find(>): if (rightPos == string::npos) { inTag = done = true: s.erase(leftPos): else s.erasedeftPos, rightPos - leftPos + 1): else done = true: Удаление всех специальных символов HTML replaceAlKs, Sit: . < ): replaceAl 1 (s. Sgt: , > ): replaceAlKs. Samp: , S ): replaceAlKs. Snbsp: , ): И т. д. return s: int main(int argc. char* argv[]) { requireArgs(argc. 1, usage: HTMLStripper InputFile ): ifstream in(argv[l]): assure(in. argv[l]): string s: while(getline(in. s)) if (!stripHTMLTags(s).empty()) cout s endl: } III:- Программа удаляет даже теги HTML, занимающие несколько строк*. Для этого используется статический флаг inTag, которому присваивается true, если при об- Ради простоты приведенная версия не обрабатывает вложенные теги (например, комментарии). Ha первый взгляд кажется, что простые математические вычисления позволят исключить часть вызовов erase(), но так как в некоторых случаях один из операндов равен string::npos (наибольшее беззнаковое целое), произойдет целочисленное переполнение, которое нарушит работу алгоритма. наружении начального тега парный завершающий тег не был обнаружен в той же строке. В функции stripHTMLFlags() встречаются все формы функции erase(). Используемая версия getlineO представляет собой глобальную функцию, объявленную в заголовочном файле <string>; она удобна тем, что в аргументе string может храниться строка произвольной длины. Нам не приходится беспокоиться о размерах символьного массива, как при использовании функции istream::getline(). В программе задействована функция replaceAU(), упоминавшаяся ранее в этой главе. В следующей главе будет создано более элегантное решение с применением строковых потоков. Сравнение строк сравнение строк принципиально отличается от сравнения чисел. Числа обладают постоянными значениями, смысл которых всегда и везде одинаков. Но для сравнения двух строк требуются лексические сравнения. Иначе говоря, когда вы проверяете символ и определяете, больше или меньше он, чем другой, вы в действительности сравниваете числовые представления этих символов в выбранной кодировке. Чаще всего используется кодировка ASCII, в которой печатные символы английского языка представляются десятичными числами в интервале от 32 до 127. В кодировке ASCII список символов начинается слробела, далее следуют некоторые знаки препинания, а затем буквы верхнего и нижнего регистра. Таким образом, буквы в начале алфавита имеют меньшие ASCII-коды, чем буквы в конце алфавита. Учитывая это обстоятельство, проще запомнить, что фраза sl меньше s2 при лексическом сравнении просто означает, что первый различающийся символ в строке si находится ближе к концу алфавита, чем символ в соответствующей позиции s2. В С++ предусмотрено несколько способов сравнения строк, каждый из которых обладает своими достоинствами и недостатками. Проще всего использовать перегруженные внешние (то есть не функции класса) операторные функции оре-rator==, operator! , operator>, operator<, operator>= и operator<=. : СОЗ:CompStr.h #ifndef COMPSTR H #define COMPSTR H #include <string> #include ../TestSuite/Test.h using std::string: class CompStrTest : public TestSuite::Test { public: void runO { Сравниваемые строки string slCThis ): string s2( That ); testjsl == si): test (sl != s2): test (sl > s2): test (si >= s2): testjsl > si): testJsZ < si): testJsZ <= si): testjsl <= si): #endif COMPSTR H /:- : C03:CompStr.cpp {L} ../TestSuite/Test #include CompStr.h int mainO { CompStrTest t: t.runO: return t.reportO: } III:- Перегруженные операторы сравнения обычно применяются для сравнения как целых строк, так и их отдельных символов. В следующем примере обратите внимание на гибкость типов аргументов в левой и правой частях операторов сравнения. Для повыщения эффективности в классе string определены перегруженные операторы для прямых сравнений строковых объектов, литералов в кавычках и указателей на строки С; это позволяет обойтись без создания временных объектов string. : СОЗ:Equivalence.срр #include <iostream> #include <string> using namespace std: int mainO { string s2( That ). slCThis ): В левой части находится литерал в кавычках. в правой части - объект string if( That == s2) cout A match endl; В левой части находится объект string. а в правой - указатель на строку в стиле С. завершенную нуль-терминатором. if(sl != s2.c str()) cout No match endl; } III:- Функция c str() возвращает const char* - указатель на строку С, заверщенную нуль-символом, которая эквивалентна текущему содержимому объекта string. Такая возможность задействуется при передаче объектов string стандартным функциям С, например функции atoi() или любым функциям, определенным в заголовочном файле <cstring>. Использование значения, возвращаемого c str(), в качестве неконстантного аргумента функции является ошибкой. Среди операторов сравнения строк отсутствуют операторы логического отрицания (!) и конъюнкции/дизъюнкции (также вы не найдете перегруженных версий поразрядных операторов С &, , и ~). Перегруженные внешние операторы сравнения для класса string ограничиваются подмножеством, имеющим четкое однозначное применение к отдельным символам или их группам.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |