C++. Сборник рецептов - [75]

Шрифт
Интервал

>out.setf(std::ios_base::right);

Но выравнивание по правому краю не имеет смысла без установки правого поля, по которому требуется выравнивать. Чтобы установить это поле, используйте >ios_base::width, как здесь.

>out.width(w);

Этот код устанавливает ширину выходного поля для передаваемого значения, что означает, что при выравнивании текста по правому краю начало строки будет дополняться пробелами так, чтобы ее правый край достиг правого поля. Заметьте, что ширину я задаю в цикле, в то время как флаг >right я выставляю перед ним. Это требуется делать потому, что после каждой записи в поток ширина сбрасывается в ноль. Флаги форматирования после записи не сбрасываются, так что их можно указать только один раз.

Однако всегда следует быть аккуратным и точным, так что при использовании флагов форматирования требуется сделать еще одну вещь: убрать их за собой.

Часто потоки, в которые производится запись, не принадлежат записывающему коду, особенно при написании библиотеки или API общего назначения. Например, если написать функцию журналирования, которая принимает выходной поток и >string, изменяет >string, устанавливает флаги форматирования и записывает >string в поток, то могут возникнуть нежелательные побочные эффекты. После того как клиентский код вызывает эту функцию журналирования, его поток содержит другой набор флагов форматирования. Решением является копирование старых флагов и восстановление их по окончании работы.

Например, функция журналирования ошибок может выглядеть вот так.

>using namespace std;


>void logFrror(ostream& out, const string& s) {

> string tmp(s);

> tmp.insert(0, "ERROR: ");

> ios_base::fmtflags figs =  // setf возвращает

>  out.setf(ios_base::left); // флаги, которые уже

>                            // были установлены

> out.width(72);

> out << tmp << '\n';

> out.flags(flgs); // вернуть оригинальные

>}

Метод >flags работает аналогично >setf, но не объединяет с помощью OR переданные ему флаги с уже установленными, а заменяет их. Таким образом, при вызове >flags и передаче ему оригинальных флагов форматирования можно быть уверенным, что флаги будут восстановлены.

4.21. Замена в текстовом файле последовательностей пробелов на один пробел

Проблема

Имеется текстовый файл с последовательностями пробелов различной длины и требуется заменить каждое вхождение такой последовательности на единственный пробел.

Решение

Для чтения непрерывной последовательности непробельных символов из потока в строку используйте шаблон функции >operator>>, определенный в >. Затем используйте его двойника >operator<<, который записывает каждую из этих последовательностей в выходной поток, и после каждой из них добавьте по одному пробелу. Пример 4.30 дает краткий пример этой методики.

Пример 4 30. Замена последовательностей пробелов на один пробел

>#include

>#include

>#include


>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);

> string tmp;

> in >> tmp;  // Прочитать первое слове

> out << tmp; // Записать его в выходной поток

> while (in >> tmp) { // operator>> игнорирует пробелы, так что все, что

>  out << ' ';        // я должен сделать, - это записать пробел и каждую

>  out << tmp;        // последовательность «непробелов»

> }

> out.close();

>}

Обсуждение

Это просто сделать, если использовать потоки и строки. Даже если требуется реализовать другой вариант этого — например, чтобы сохранить переходы на новую строку, — эта методика будет работать. Если требуется добавить переходы на новые строки, для их расстановки в нужных местах используйте решение, представленное в рецепте 4.16.

Смотри также

Рецепты 4.15 и 4.16.

4.22. Автозамена текста при изменении буфера

Проблема

Имеется класс, который представляет некий тип текстового поля или документа, и по мере добавления в него текста требуется автоматически корректировать неправильно написанные слова, как это делает функция Autocorrect (Автозамена) в Microsoft Word.

Решение

Это можно реализовать в относительно небольшом коде, если использовать >map, который определен в >, >string и различные возможности стандартной библиотеки. Пример 4.31 показывает, как это делается.

Пример 4.31. Автозамена текста

>#include

>#include

>#include

>#include


>using namespace std;


>typedef map StrStrMap;


>// Класс для хранения текстовых полей

>class TextAutoField {

>public:

> TextAutoField(StrStrMap* const p) : pDict_(p) {}

> ~TextAutoField() {}

> void append(char c);

> void getText(string& s) {s = buf_;}

>private:

> TextAutoField();

> string buf_;

> StrStrMap* const pDict ;

>};


>// Добавление с автозаменой

>void TextAutoField::append(char c) {

> if ((isspace(c) || ispunct(c)) &&     // Выполнять автоза-

>  buf_.length() > 0 &&                 // мену, только когда вводятся

>  !isspace(buf_[buf_.length() - 1])) { // ws или punct

>  string::size_type i = buf_.find_last_of(" \f\n\r\t\v");

>  i = (i == string::npos) ? 0 : ++i;

>  string tmp = buf_.substr(i, buf_.length() - i);

>  StrStrMap::const_iterator p = DDict_->find(tmp);


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.