Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

while (!(buffer>>s)) { // попытка прочитать символы из буфера

if (buffer.bad || !source.good) return *this;

buffer.clear;

// заполняем объект buffer

}

Если объект

buffer
находится в состоянии
bad
или существуют проблемы с источником данных, работа прекращается; в противном случае объект
buffer
очищается и выполняется новая попытка. Мы должны очистить объект
buffer
, потому что попадем в “цикл заполнения”, только если попытка ввода закончится неудачей. Обычно это происходит, если вызывается функция
eof
для объекта
buffer;
иначе говоря, когда в объекте
buffer
не остается больше символов для чтения. Обработка состояний потока всегда запутанна и часто является причиной очень тонких ошибок, требующих утомительной отладки. К счастью, остаток цикла заполнения вполне очевиден.

string line;

getline(source,line); // вводим строку line из потока source

// при необходимости выполняем замену символов

for (int i =0; i<line.size; ++i)

if (is_whitespace(line[i]))

line[i]= ' '; // в пробел

else if (!sensitive)

line[i] = tolower(line[i]); // в нижний регистр

buffer.str(line); // вводим строку в поток

Считываем строку в объект

buffer
, затем просматриваем каждый символ строки в поисках кандидатов на замену. Функция
is_whitespace
является членом класса
Punct_stream
, который мы определим позднее. Функция
tolower
— это стандартная библиотечная функция, выполняющая очевидное задание, например превращает символ
A
в символ
a
(см. раздел 11.6).

После правильной обработки строки

line
ее необходимо записать в поток
istringstream
. Эту задачу выполняет функция
buffer.str(line);
эту команду можно прочитать так: “Поместить строку из объекта
buffer
класса
istringstream
в объект
line
”.

Обратите внимание на то, что мы “забыли” проверить состояние объекта

source
после чтения данных с помощью функции
getline
. Это не обязательно, поскольку в начале цикла выполняется проверка условия
!source.good
.

Как всегда, оператор

>>
возвращает ссылку на поток
*this
(раздел 17.10).

Проверка разделителей проста; мы сравниваем символ с каждым символом из строки, в которой записаны разделители.

bool Punct_stream::is_whitespace(char c)

{

for (int i = 0; i<white.size; ++i)

if (c==white[i]) return true;

return false;

}

Напомним, что поток

istringstream
обрабатывает обычные разделители (например, символы перехода на новую строку или пробел) по-прежнему, поэтому никаких особых действий предпринимать не надо.

Осталась одна загадочная функция.

Punct_stream::operator bool

{

return !(source.fail || source.bad) && source.good;

}

Обычное использование потока

istream
сводится к проверке результата оператора
>>
. Рассмотрим пример.

while (ps>>s) { /* ... */ }

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

ps>>s
, представленного в виде булевого значения. Результатом инструкции
ps>>s
является объект класса
Punct_stream
, поэтому нам нужен способ неявного преобразования класса
Punct_stream
в тип
bool
. Эту задачу решает функция operator
bool
в классе
Punct_stream
.

Функция-член operator

bool
определяет преобразование класса
Punct_stream
в тип
bool
. В частности, она возвращает значение
true
, если эта операция над классом
Punct_stream
прошла успешно.

Теперь можем написать программу.

int main

// вводит текст и создает упорядоченный список всех слов

// из заданного текста, игнорируя знаки пунктуации и регистры,

// а также удаляя дубликаты из полученного результата

{

Punct_stream ps(cin);

ps.whitespace(";:,.?!\"{}<>/&$@#%^*|~"); // \" в строке

// означает "

ps.case_sensitive(false);

cout << "Пожалуйста, введите слова \n";

vector<string> vs;

string word;

while (ps>>word) vs.push_back(word); // ввод слов

  • Читать дальше
  • 1
  • ...
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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