Представьте следующую входную строку: "a00000"
"a1"
, поскольку в ней содержится только один символ, 'a'
. За ним следует пять символов '0'
, что даст результат "05"
. Итоговый результат выглядит как "a105"
. К сожалению, эта сжатая строка гласит: Чтобы это предотвратить, функция compress может, например, отвергать входные данные, содержащие числа, или особым образом их помечать. А алгоритм decompress способен принимать еще одно условное выражение, которое ограничивает максимальный размер итоговой строки. Попробуйте выполнить данное упражнение самостоятельно.
Глава 7
Строки, классы потоков и регулярные выражения
В этой главе:
□ создание, конкатенация и преобразование строк;
□ удаление пробелов из начала и конца строк;
□ преимущества использования std::string
std::string
;□ чтение значений из пользовательского ввода;
□ подсчет всех слов в файле;
□ форматирование ваших выходных данных с помощью манипуляторов потока ввода/вывода;
□ инициализация сложных объектов из файла вывода;
□ заполнение контейнеров с применением итераторов std::istream
□ вывод любых данных на экран с помощью итераторов std::ostream
□ перенаправление выходных данных в файл для конкретных разделов кода;
□ создание пользовательских строковых классов путем наследования std::char_traits
□ токенизация входных данных с помощью библиотеки для работы с регулярными выражениями;
□ удобный и красивый динамический вывод чисел на экран в зависимости от контекста;
□ перехват читабельных исключений для ошибок потока std::iostream
Введение
Данная глава посвящена обработке строк, анализу и выводу на экран произвольных данных. Для этих задач STL предоставляет потоковую библиотеку
Стрелки показывают схему наследования классов. Рисунок на первый взгляд может показаться непонятным, но в рамках главы мы рассмотрим все классы и познакомимся с ними по очереди. Если мы попробуем обратиться к документации С++ в STL, то не найдем упомянутые классы по
basic_
(например, в документации STL проще найти класс basic_istream
, в отличие от istream
). Классы для работы с потоками, которые начинаются с префикса basic_*
, являются шаблонными, они могут быть специализированы для разных типов символов. Классы, показанные на рис. 7.1, специализированы для значений типа char
. В книге мы будем применять именно эти специализации. Если мы воспользуемся префиксом w
для упомянутых имен класса, то получим названия wistream
, wostream
и т.д. — они являются специализациями для типа wchar_t
вместо char
.В верхней части рис. 7.1 мы видим класс std::ios_base
std::ios
, она воплощает идею объекта, сопровождающего поток данных, который может находиться в Первыми специализациями, которые мы применим на самом деле, являются std::istream
std::ostream
. Префиксы "i"
и "o"
расшифровываются как input
и output
(«ввод» и «вывод»). Мы уже видели такие префиксы на раннем этапе программирования на С++ в простейших примерах в объектах std::cout
и std::cin
(а также std::cerr
). Экземпляры этих классов всегда доступны глобально. Мы выполняем вывод данных с помощью ostream
, а ввод — с использованием input
.Класс, который наследует от классов istream
ostream
, называется iostream
. С его помощью можно выполнять как ввод, так и вывод данных. Зная, как использовать все классы из трио istream
, ostream
и iostream
, вы сможете незамедлительно применить следующие классы:□ классы ifstream
ofstream
и fstream
наследуют от классов istream
, ostream
и iostream
соответственно, но задействуют их возможности, чтобы перенаправить ввод/вывод в файлы или из них из