Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Функции

find_from_addr
и
find_subject
не имеют конкретного содержания, пока мы не выясним, как идентифицировать информацию в файле (используя регулярные выражения и из разделов 23.6–23.10).

int is_prefix(const string& s, const string& p)

// Является ли строка p первой частью строки s?

{

int n = p.size;

if (string(s,0,n)==p) return n;

return 0;

}

bool find_from_addr(const Message* m, string& s)

{

for(Line_iter p = m–>begin; p!=m–>end; ++p)

if (int n = is_prefix(*p,"From: ")) {

s = string(*p,n);

return true;

}

return false;

}

string find_subject(const Message* m)

{

for(Line_iter p = m.begin; p!=m.end; ++p)

if (int n = is_prefix(*p,"Subject: "))

return
string(*p,n);

return "";

}

Обратите внимание на то, как мы используем подстроки: конструктор
string(s,n)
создает строку, состоящую из хвоста строки
s
, начиная с элемента
s[n]
(т.е.
s[n]..s[s.size–1]
), а конструктор
string(s,0,n)
создает строку, состоящую из символов
s[0]..s[n–1]
. Поскольку эти операторы на самом деле создают новые строки и копируют символы, они должны использоваться очень осторожно, чтобы не снизить производительность программы.

Почему функции
find_from_addr
и
find_subject
так отличаются друг от друга? Например, одна из них возвращает переменную типа
bool
, а другая — объект класса
string
. Потому что мы хотели подчеркнуть следующие моменты.

• Функция

find_from_addr
различает поиск пустой строки адреса (
""
) и поиск отсутствующей строки адреса. В первом случае функция
find_from_addr
возвращает значение
true
(поскольку она нашла адрес) и присваивает строке
s
значение
""
(потому что адресная строка просто оказалась пустой). Во втором случае она возвращает значение
false
(поскольку в файле вообще не оказалось адресной строки).

• Функция

find_subject
возвращает строку
""
и когда строка темы сообщения оказалась пустой, и когда ее вообще нет.

Насколько полезным является такое различие, которое проводит функция

find_from_addr
? Необходимо ли это? Мы считаем, что это полезно и необходимо. При поиске информации в файле данных это различие проявляется снова
и снова: нашли ли мы искомую строку и содержит ли она то, что нам нужно? В реальной программе обе функции,
find_from_addr
и
find_subject
, следовало бы написать в стиле функции
find_from_addr
, чтобы дать пользователям возможность проводить такое различие.

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

multimap
классом
unordered_multimap
, но без испытаний невозможно сказать, насколько это повысит эффективность программы.

Введение в стандартные ассоциативные контейнеры (

map
,
multimap
,
set
,
unordered_map
и
unordered_multimap
) см. в разделе 21.6.

23.5. Проблема

Потоки ввода-вывода и класс

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

string s;

while (cin>>s) {

if (s.size==7

&& isalpha(s[0]) && isalpha(s[1])

&& isdigit(s[2]) && isdigit(s[3]) && isdigit(s[4])

&& isdigit(s[5]) && isdigit(s[6]))

cout << " найдена " << s << '\n';

}

Здесь значение

isalpha(x)
равно
true
, если
x
— это буква, а значение
isdigit(x)
равно
true
, если
x
— цифра (см. раздел 11.6). В этом (слишком) простом решении кроется несколько проблем.

• Оно громоздко (четыре строки, восемь вызовов функций).

• Мы пропускаем (умышленно?) почтовые индексы, не отделенные от своего контекста пробелом (например, "TX77845", TX77845–1234 и ATX77845).

• Мы пропускаем (умышленно?) почтовые индексы с пробелом между буквами и цифрами (например, TX 77845).

• Мы принимаем (умышленно?) почтовые индексы, в которых буквы набраны в нижнем регистре (например, tx77845).

• Если вы решите проанализировать почтовые индексы, имеющие другой формат (например, CB3 0FD), то будете вынуждены полностью переписать весь код.

Должен быть более хороший способ! Перед тем как его описать, рассмотрим поставленные задачи. Предположим, что мы хотим сохранить “старый добрый код”, дополнив его обработкой указанных ситуаций.

• Если мы хотим обрабатывать не один формат, то следует добавить инструкцию

if
или
switch
.

Поделиться:
Популярные книги

Столичный доктор. Том III

Вязовский Алексей
3. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том III

Бремя империи

Афанасьев Александр
Бремя империи - 1.
Фантастика:
альтернативная история
9.34
рейтинг книги
Бремя империи

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Герцогиня в ссылке

Нова Юлия
2. Магия стихий
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Герцогиня в ссылке

Помещица Бедная Лиза

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Помещица Бедная Лиза

Менталист. Конфронтация

Еслер Андрей
2. Выиграть у времени
Фантастика:
боевая фантастика
6.90
рейтинг книги
Менталист. Конфронтация

В теле пацана 4

Павлов Игорь Васильевич
4. Великое плато Вита
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
В теле пацана 4

Я уже князь. Книга XIX

Дрейк Сириус
19. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я уже князь. Книга XIX

Последняя Арена 5

Греков Сергей
5. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 5

Пистоль и шпага

Дроздов Анатолий Федорович
2. Штуцер и тесак
Фантастика:
альтернативная история
8.28
рейтинг книги
Пистоль и шпага

Гром над Империей. Часть 1

Машуков Тимур
5. Гром над миром
Фантастика:
фэнтези
5.20
рейтинг книги
Гром над Империей. Часть 1

Ночь со зверем

Владимирова Анна
3. Оборотни-медведи
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Ночь со зверем

Везунчик. Проводник

Бубела Олег Николаевич
3. Везунчик
Фантастика:
фэнтези
6.62
рейтинг книги
Везунчик. Проводник

Шесть тайных свиданий мисс Недотроги

Суббота Светлана
Любовные романы:
любовно-фантастические романы
эро литература
7.75
рейтинг книги
Шесть тайных свиданий мисс Недотроги