- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
C++. Сборник рецептов - Д. Стефенс
Шрифт:
Интервал:
Закладка:
back_inserter(tmp), // к верхнему регистру
toupper);
return(search(s.begin(), s.end(), // Возвращаем итератор.
tmp.begin(), tmp.end(), // возвращаемый из
caseInsCharCompSingle)); // search
}
int main() {
string s = "row, row, row, your boat";
string p = "YOUR";
string::const_iterator ir = caseInsFind(s, p);
if (it != s.end()) {
cout << "Нашли!n;
}
}
Возвращая итератор, который указывает на элемент целевой строки, где начинается шаблонная строка, мы обеспечиваем совместимость с другими стандартными алгоритмами, так как большинство из них принимают в качестве аргумента итератор.
ОбсуждениеПример 4.22 демонстрирует обычный ход действий при работе со стандартными алгоритмами. Создайте функцию, которая выполняет работу, а затем подключите ее как объект функции к наиболее подходящему алгоритму. Здесь работу выполняет функция charInsCharCompSingle, но в отличие от примера 4.21 эта функция сравнения символов переводит к верхнему регистру только первый аргумент. Это сделано потому, что немного далее в caseInsFind я перед использованием строки шаблона в поиске преобразую ее к верхнему регистру полностью и тем самым избегаю многократного преобразования символов строки шаблона к верхнему регистру.
После того как функция сравнения будет готова, используйте для поиска стандартные алгоритмы transform и search. transform используется для преобразования к верхнему регистру всего шаблона (но не целевой строки). После этого используйте для поиска места вхождения подстроки search совместно с функцией сравнения.
Помните, что стандартные алгоритмы работают с последовательностями, а не со строками. Это общие алгоритмы, которые в основном (но не только) работают со стандартными контейнерами, но не делают никаких предположений о содержимом этих контейнеров. Все стандартные алгоритмы требуют передачи им функции сравнения (а в случае их отсутствия используют операторы по умолчанию), которые тем или иным способом сравнивают два элемента и возвращают bool, указывающий, дало ли сравнение истину или ложь.
В примере 4.22 есть одна вещь, которая выглядит странно. Вы видите, что caseInsCompare возвращает const_iterator, как в
string::const_iterator caseInsFind(const string& s,
const string& p)
Что, если требуется изменить элемент, на который указывает возвращенный итератор? Тому есть причина. Она состоит в том, что константный итератор используется потому, что строки, которые передаются в caseInsFind, также передаются как const, и, следовательно, невозможно получить не-const итератор на const-строку. Если требуется итератор, который можно использовать для изменения строки, удалите const из параметров и измените объявление функции так, чтобы она возвращала string::iterator.
4.15. Преобразование между табуляциями и пробелами в текстовых файлах
ПроблемаИмеется текстовый файл, содержащий табуляции или пробелы, и требуется преобразовать одни в другие. Например, может потребоваться заменить все табуляции на последовательности из трех пробелов или сделать наоборот и заменить все вхождения некоторого числа пробелов на табуляции.
РешениеНезависимо от того, производится ли замена табуляций на пробелы или пробелов на табуляции, используйте классы ifstream и ofstream из <fstream>. В первом (более простом) случае прочтите данные по одному символу с помощью входного потока, изучите их и, если очередной символ — это табуляция, запишите в выходной поток некоторое количество пробелов. Пример 4.23 демонстрирует, как это делается.
Пример 4.23. Замена табуляций на пробелы
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main(int argc, char** argv) {
if (argc < 3)
return(EXIT_FAILURE);
ifstream in(argv[1]);
ofstream out(argv[2]);
if (!in || !out) return(EXIT_FAILURE);
char c;
while (in.get(c)) {
if (c == 't')
out << " "; // 3 пробела
else
out << c;
}
out.close();
if (out)
return(EXIT_SUCCESS);
else
return(EXIT_FAILURE);
}
Если же требуется заменить пробелы на табуляции, обратитесь к примеру 4.24. Он содержит функцию spacesToTabs, которая читает из входного потока по одному символу, ища три последовательных пробела. Когда они найдены, она записывает в выходной поток табуляцию. Для всех остальных символов или меньшего количества пробелов в выходной поток записывается то, что было прочитано во входном.
Пример 4.24. Замена пробелов на табуляции
#include <iostream>
#include <istream>
#include <ostream>
#include <fstream>
#include <cstdlib>
using namespace std;
void spacesToTabs(istream& in, ostream& out, int spaceLimit) {
int consecSpaces = 0;
char c;
while (in.get(c)) {
if (c != ' ') {
if (consecSpaces > 0) {
for (int i = 0; i < consecSpaces; i++) {
out.put(' ');
}
consecSpaces = 0;
}
out.put(c);
} else {
if (++consecSpaces == spaceLimit) {
out.put('t');
consecSpaces = 0;
}
}
}
}
int main(int argc, char** argv) {
if (argc < 3)
return(EXIT_FAILURE);
ifstream in(argv[1]);
ofstream out(argv[2]);
if (!in || !out)
return(EXIT_FAILURE);
spacesToTabs(in, out, 3);
out.сlose();
if (out)
return(EXIT_SUCCESS);
else
return(EXIT_FAILURE);
}
ОбсуждениеМеханизм обоих этих решений один и тот же, отличаются только алгоритмы. Символы читаются из входного потока с помощью get, а в выходной поток помещаются с помощью put. Логика, выполняющая преобразования, помещается между этими двумя функциями.
Вы, вероятно, заметили в примере 4.24, что в функции main in и out объявлены как переменные типов ifstream и ofstream соответственно и что параметры spacesToTabs — это istream и ostream. Это сделано для того, чтобы позволить spacesToTabs работать с любыми типами входных и выходных потоков (ну, не любыми типами потоков, а теми, которые наследуются от basic_istream или basic_ostream), а не только с файловыми потоками. Например, текст, который требуется переформатировать, может находиться в строковом потоке (istringstream и ostringstream из <sstream>). В этом случае сделайте что-то похожее на следующее.
istringstream istr;
ostringstream ostr;
// заполняем istr текстом...
spacesToTabs(istr, ostr);
Как и в случае со строками, потоки — это на самом деле шаблоны классов, параметризованные по типу символов, с которыми работает поток. Например, ifstream — это typedef для basic_ifstream<char>, a wifstream — это typedef для basic_ifstream<wchar_t>. Таким образом, если требуется, чтобы spacesToTabs из примеров 4.23 или 4.24 работала с потоками любых символов, то вместо typedef используйте эти шаблоны классов.
template<typename T>
void spacesToTabs(std::basic_istream<T>& in,
std::basic_ostream<T>& out, int spaceLimit) { //...
4.16. Перенос строк в текстовом файле
ПроблемаТребуется сделать перенос текста файла после определенного количества символов. Например, если требуется сделать перенос текста после 72 символов, то после каждого 72 символа файла требуется вставить символ новой строки. Если файл содержит текст, читаемый человеком, то, вероятно, потребуется избежать разделения слов.
РешениеНапишите функцию, которая использует входной и выходной потоки, читает символы с помощью istream::get(char), выполняет какие-либо действия и записывает символы с помощью ostream::put(char). Пример 4.25 показывает, как это делается с файлом, который содержит обычный текст, с учетом сохранения целостности слов.
Пример 4.25. Перенос текста
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cctype>
#include <functional>
using namespace std;
void textWrap(istream& in, ostream& out, size_t width) {
string tmp;
char cur = ' ';
char last = ' ';
size_t i = 0;
while (in.get(cur)) {
if (++i == width) {
ltrimws(tmp); // ltrim как в рецепте

