Назад | Начало урока | Вперед
Содержание

Глава 3

Удаление символов из строк
Функция erase() класса string легко и эффективно удаляет символы из строк. Функция получает два аргумента: начальную позицию удаления (по умолчанию 0) и количество удаляемых символов (по умолчанию string::npos). Если заданное количество символов больше количества оставшихся символов в строке, стираются все символы до конца (таким образом, вызов erase() без аргументов удаляет из строки все символы).

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

В следующем примере для решения этой задачи используется функция erase():

Вверх


//: C03:HTMLStripper.cpp {RunByHand}
//{L} ReplaceAll
// Фильтр для удаления тегов и маркеров HTML
#include <cassert>
#include <cmath>
#include <cstddef>
#include <fstream>
#include <iostream>
#include <string>
#include "ReplaceAll.h"
#include "../require.h"
using namespace std;

string& stripHTMLTags(string& 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.erase();
}
}
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.erase(leftPos, rightPos - leftPos + 1);
}
else
done = true;
}
}
// Удаление всех специальных символов HTML
replaceAll(s, "& lt;", "& lt");
replaceAll(s, "& gt;", "& gt");
replaceAll(s, "& amp;", "&");
replaceAll(s, "& nbsp;", " ");
// E o. a.
return s;
}

int main(int argc, char* argv[]) {

requireArgs(argc, 1, "usage: HTMLStripper InputFile");
ifstream in(argv[1]);
assure(in, argv[1]);
string s;
while(getline(in, s))
if (!stripHTMLTags(s).empty())
cout << s << endl;

} ///:~


Результат:

Анализ:

Программа удаляет даже теги html, занимающие несколько строк. Для этого используется статический флаг inTag, которому присваивается true, если при обнаружении начального тега парный завершающий тег не был обнаружен в той же строке. В функции stripHTMLTags() встречаются все формы функции erase().

Используемая версия getline() представляет собой глобальную функцию, объявленную в заголовочном файле <string> она удобна тем, что в аргументе string может храниться строка произвольной длины. Нам не приходится беспокоиться о размерах символьного массива, как при использовании функции stream::getline().

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


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz