Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Длина самого длинного слова 10

Читайте также:
  1. Corsani В., LApocalisse [Откровение св. Иоанна Богослова], Torino: Claudiana, 1987.
  2. Fashion-словарь
  3. Grammar: система часів англійського дієслова (повторення); узгодження часів; пряма та непряма мова.
  4. I. Прежде всего, возьмем СЛОВА СТИХА: "Уврачую отпадение их".
  5. I. Терминологический словарь
  6. IV. Адыгейско - русский словарь наиболее употребляемых фраз
  7. Lt;question> Дословная выдержка из какого-либо текста, сочинения или дословно приводимые чьи-либо слова.

Самое длинное слово creature,"

На самом деле этот результат неправилен: самое длинное слово beautiful, в нем девять букв. Однако выбрано creature, потому что программа сочла его частью запятую и кавычку. Следовательно, необходимо отфильтровать небуквенные символы.

Но прежде чем заняться этим, рассмотрим программу внимательнее. В ней каждое слово помещается в массив buf, длина которого равна 24. Если бы в тексте попалось слово длиной 24 символа (или более), то буфер переполнился бы и программа, вероятно, закончилась бы крахом. Чтобы предотвратить переполнение входного массива, можно воспользоваться манипулятором setw(). Модифицируем предыдущую программу:

while (cin > > setw(bufSize) > > buf)

Здесь bufSize – размер массива символов buf. setw() разбивает строку длиной bufSize или больше на несколько строк, каждая из которых не длиннее, чем bufSize - 1.

Завершается такая частичная строка двоичным нулем. Для использования setw() в программу необходимо включить заголовочный файл iomanip:

#include <iomanip>

Если в объявлении массива buf размер явно не указан:

char buf[] = "Нереалистичный пример";

то программист может применить оператор sizeof, но при условии, что идентификатор является именем массива и находится в области видимости выражения:

while (cin > > setw(sizeof(buf))> > buf)

Применение оператора sizeof в следующем примере дает неожиданный результат:

#include <iostream>#include <iomanip>int main(){ const int bufSize = 24; char buf[ bufSize ]; char *pbuf = buf; // если строка длиннее, чем sizeof(char*), // она разбивается на несколько строк while (cin > > setw(sizeof(pbuf)) > > pbuf) cout << pbuf < <endl;}

Программа печатает:

$ a.outThe winter of our discontentThewinterofourdiscontent

Функции setw() вместо размера массива передается размер указателя, длина которого на нашей машине равна четырем байтам, поэтому вывод разбит на строки по три символа.

Попытка исправить ошибку приводит к еще более серьезной проблеме:

while (cin >> setw(sizeof(*pbuf)) >> pbuf)

Мы хотели передать setw() размер массива, адресуемого pbuf. Но выражение

*pbuf

дает только один символ, т.е. объект типа char. Поэтому setw() передается значение 1. На каждой итерации цикла while в массив, на который указывает pbuf, помещается только нулевой символ. До чтения из стандартного ввода дело так и не доходит, программа зацикливается.

При использовании класса string все проблемы управления памятью исчезают, об этом заботится сам string. Вот как выглядит наша программа в данном случае:

#include <iostream.h>#include <string>int main(){ string buf, largest; // для хранения статистики int curLen, // длина текущего слова max = -1, // максимальная длина слова cnt = 0; // счетчик прочитанных слов while (cin > >buf) { curLen = buf.size(); ++cnt; // новое самое длинное слово? сохраним его if (curLen > max) { max = curLen; largest = buf; } } cout < "Число прочитанных слов " << cnt << endl; cout << "Длина самого длинного слова " << max << endl; cout << "Самое длинное слово " << largest << endl;}

Однако запятая и кавычка по-прежнему считаются частью слова. Напишем функцию для удаления этих символов из слова:

#include <string>void filter_string(string &str){ // элементы, подлежащие фильтрации string filt_elems("\",?."); string::size_type pos = 0; while ((pos = str.find_first_of(filt_elems, pos))!= string::npos) str.erase(pos, 1);}

Эта функция работает правильно, но множество символов, которые мы собираемся отбрасывать, "зашито" в код. Лучше дать пользователю возможность самому передать строку, содержащую такие символы. Если он согласен на множество по умолчанию, то может передать пустую строку.

#include <string>void filter_string(string &str, string filt_elems = string("\",.")){ string::size_type pos = 0; while ((pos = str.find_first_of(filt_elems, pos))!= string::npos) str.erase(pos, 1);}

Более общая версия filter_string() принимает пару итераторов, обозначающих диапазон, где производится фильтрация:

template <class InputIterator>void filter_string(InputIterator first, InputIterator last, string filt_elems = string("\",.")){ for (; first!= last; first++) { string::size_type pos = 0; while ((pos = (*first).find_first_of(filt_elems, pos))!= string::npos) (*first).erase(pos, 1); }}

С использованием этой функции программа будет выглядеть так:

#include string>#include <algorithm>#include <iterator>#include <vector>#include <iostream> bool length_less(string s1, string s2) { return s1.size() < s2.size(); } int main(){ istream_iterator< string > input(cin), eos; vector< string > text; // copy - это обобщенный алгоритм copy(input, eos, back_inserter(text)); string filt_elems("\",.;:"); filter_string(text.begin(), text.end(), filt_elems); int cnt = text.size(); // max_element - это обобщенный алгоритм string *max = max_element(text.begin(), text.end(), length_less); int len = max->size(); cout << "Число прочитанных слов " << cnt << endl; cout << "Длина самого длинного слова " << len << endl; cout << "Самое длинное слово " << *max << endl;}

Когда мы применили в алгоритме max_element() стандартный оператор "меньше", определенный в классе string, то были удивлены полученным результатом:


Дата добавления: 2015-09-03; просмотров: 116 | Нарушение авторских прав


Читайте в этой же книге: Неполный конструктор | Перезагрузка конструкторов | Перегрузка операций (операторов). Понятие перегрузки операторов. Синтаксис перегрузки операции. Перегрузка бинарных операторов. | Перегрузка операций (операторов). Перегрузка операторов отношения и логических операторов. Перегрузка оператора присваивания. Перегрузка унарных операторов. | Перегрузка операций (операторов). Перегрузка операторов инкремента и декремента. Перегрузка оператора индексирования. Перегрузка оператора вызова функции. | Перегрузка операций (операторов). Перегрузка операторов доступа к членам класса. Перегрузка операторов new и delete. Функции преобразования типа. | Полиморфизм и виртуальные функции. Раннее и позднее связывание. Динамический полиморфизм. Виртуальные функции. Виртуальные и невиртуальные функции. | Строковые потоки | Состояние формата (ОТНОСИТСЯ К ПОСЛЕДНЕМУ ВОПРОСУ, КОТОРЫЙ 24) | Работа с несовместимыми конструкциями. |
<== предыдущая страница | следующая страница ==>
Полиморфизм и виртуальные функции. Применение динамического полиморфизма. Виртуальные деструкторы. Абстрактные классы и чисто виртуальные функции.| Самое длинное слово beautiful

mybiblioteka.su - 2015-2024 год. (0.006 сек.)