Выбрать главу

_________________

*Примечание: это значение воздействует на вывод одного поля, после чего происходит возврат к значению по умолчанию.

«Внимательно следите за параметром ширины поля ( функция width( n ) либо манипулятор setw( n ) ). Большинство параметров сохраняют своё значение до тех пор, пока оно не будет изменено новым вызовом, однако для параметра ширины поля это не так. Этот параметр возвращается к значению по умолчанию, как только будет выполнен следующий вывод в поток. Например, приведённый ниже фрагмент кода не выведет два целочисленных значения длиной в 8 символов.» 

[Атас!]

_________________

288 стр. Часть 5. Полезные особенности

    #include <iostream>

    #include <iomanip>

    void fn( )

    {

        cout << setw( 8 ) /* ширина поля равна 8... */

             << 10      /* ...для 10 , но... */

             << 20 /* для 20 равна значению по умолчанию */

             << "\n" ;

    }

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

    #include <iostream>

    #include <iomanip>

    void fn( )

    {

        cout << setw( 8 ) /* установить ширину... */

             << 10    

             << setw( 8 )

             << 20 /* ...обновить её */

             << "\n" ;

    }

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

Какой же метод лучше — с использованием манипуляторов или функций? Функции-члены предоставляют больше контроля над свойствами потока — хотя бы потому, что их больше. Кроме того, функции-члены обязательно возвращают предыдущее значение изменяемого параметра, так что у вас всегда есть возможность восстановить прежнее значение параметра. И наконец, существуют версии этих функций, позволяющие узнать текущее значение параметра, не изменяя его. Использование этой возможности показано в приведённом ниже примере.

    #include <iostream>

    void fn( float value )

    {

        int previousPrecision ;

        /* Вы можете узнать текущую точность так: */

        previousPrecision = cout.precision( ) ;

        /* Можно также сохранить старое значение, одновременно изменяя его на новое */

        previousPrecision = cout.precision( 2 ) ;

        cout << value ;

        /* Восстановим предыдущее значение */

        cout.precision( previousPrecision ) ;

    }

Несмотря на все преимущества "функционального" подхода, манипуляторы более распространены; возможно, это просто потому, что они "круче" выглядят. Используйте то, что вам больше нравится, но в чужом коде будьте готовы увидеть оба варианта.

_________________ 

289 стр. Глава 24. Использование потоков ввода-вывода

Глава 25. ОБРАБОТКА ОШИБОК И ИСКЛЮЧЕНИЯ...290

ОГЛАВЛЕНИЕ

        В этой главе...

►Зачем нужен новый механизм обработки ошибок 291

►Механизм исключительных ситуаций 293

►Так что же мы будем бросать? 295

Трудно с этим смириться, но факт остаётся фактом: иногда функции работают неправильно. Традиционно вызывающей программе сообщается об ошибке посредством возвращаемого функцией значения. Однако язык С++ предоставляет новый, улучшенный механизм выявления и обработки ошибок с помощью исключительных ситуаций, или просто исключений ( exceptions ). Исключение — это отступление от общего правила, т.е. случай, когда то или иное правило либо принцип неприменимы. Можно дать и такое определение: исключение — это неожиданное ( и, надо полагать, нежелательное ) состояние, которое возникает во время выполнения программы.