Программирование >>  Разработка устойчивых систем 

1 ... 27 28 29 [ 30 ] 31 32 33 ... 196


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 ограничиваются подмножеством, имеющим четкое однозначное применение к отдельным символам или их группам.



1 ... 27 28 29 [ 30 ] 31 32 33 ... 196

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика