📚 Hub Books: Онлайн-чтение книгРазная литератураC++17 STL Стандартная библиотека шаблонов - Яцек Галовиц

C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц

Шрифт:

-
+

Интервал:

-
+
1 ... 65 66 67 68 69 70 71 72 73 ... 121
Перейти на страницу:
123" или " 123". Можно управлять тем, с какой стороны будут вставлены символы-заполнители, используя std::left, std::right и std::internal. При выводе чисел в десятичной форме манипулятор internal выглядит похожим на right. Но если мы выведем значение 0x1, например с шириной 6 и манипулятором internal, то получим "0x 6". Манипулятор setfill определяет, какой именно символ будет применен для заполнения. Мы попробуем разные стили.

  cout << "================n";

  cout << setfill(fill_char);

  cout << left << setw(width) << val << 'n';

  cout << right << setw(width) << val << 'n';

  cout << internal << setw(width) << val << 'n';

}

4. В функции main начинаем использовать реализованную нами функцию. Сначала выведем на экран значение 12345 с шириной 15. Сделаем это дважды, но во второй раз применим заполнитель '_'.

int main()

{

  print_aligned_demo(123456, 15);

  print_aligned_demo(123456, 15, '_');

5. Затем выведем значение 0x123abc с такой же шириной. Однако прежде, чем это сделать, применим std::hex и std::showbase с целью указать объекту потока вывода cout, что он должен выводить числа в шестнадцатеричном формате и добавлять к ним префикс "0x", поскольку тогда их нельзя будет интерпретировать по-другому:

  cout << hex << showbase;

  print_aligned_demo(0x123abc, 15);

6. Сделаем то же самое и для oct, что укажет cout использовать восьмеричную систему счисления при выводе чисел. showbase все еще активен, поэтому 0 будет добавлен к каждому выводимому числу:

  cout << oct;

  print_aligned_demo(0123456, 15);

7. В случае использования hex и uppercase мы увидим, что символ 'x' в конструкции "0x" будет выведен в верхнем регистре. Сочетание 'abc' в конструкции '0x123abc' также будет в верхнем регистре:

  cout << "A hex number with upper case letters: "

       << hex << uppercase << 0x123abc << 'n';

8. Если мы хотим снова вывести число 100 в десятичной системе счисления, то нужно запомнить, что мы переключили поток в режим hex. С помощью dec вернем его в обычное состояние:

  cout << "A number: " << 100 << 'n';

  cout << dec;

  cout << "Oops. now in decimal again: " << 100 << 'n';

9. Мы также можем сконфигурировать формат вывода булевых значений. По умолчанию значение true выводится как 1, а false — как 0. С помощью boolalpha можно задать ему текстовое представление:

  cout << "true/false values: "

       << true << ", " << false << 'n';

  cout << boolalpha

       << "true/false values: "

       << true << ", " << false << 'n';

10. Взглянем на переменные с плавающей точкой типов float и double. Если нужно вывести число наподобие 12.3, то увидим 12.3. При наличии такого числа, как 12.0, поток вывода отбросит десятичную точку. Это можно изменить, использовав showpoint. С его помощью десятичная точка будет отображаться всегда:

  cout << "doubles: "

       << 12.3 << ", "

       << 12.0 << ", "

       << showpoint << 12.0 << 'n';

11. Представление чисел с плавающей точкой может иметь модификаторы scientific или fixed. Первый означает следующее: число нормализовано к такому виду, что видна только первая цифра после десятичной точки, а затем выводится экспонента, на которую нужно умножить число, чтобы получить его реальный размер. Например, значение 300.0 будет выглядеть как "3.0E2", поскольку 300 равно 3.0 * 10^2. Модификтор fixed позволяет вернуться к представлению с десятичной точкой:

  cout << "scientific double: " << scientific

       << 123000000000.123 << 'n';

  cout << "fixed double: " << fixed

       << 123000000000.123 << 'n';

12. Помимо нотации мы можем решить, какую точность будут иметь числа с плавающей точкой. Создадим очень маленькое значение и выведем его, указав точность десять знаков после запятой, а затем повторим вывод, но укажем точность один знак:

  cout << "Very precise double: "

       << setprecision(10) << 0.0000000001 << 'n';

  cout << "Less precise double: "

       << setprecision(1) << 0.0000000001 << 'n';

}

13. Компиляция и запуск программы дают следующий длинный результат. Первые четыре блока выходных данных получены от вспомогательной функции print с помощью модификаторов setw и left/right/internal. Затем мы работали с регистрами представлений системы счисления, представлениями булевых чисел, а также форматированием чисел с плавающей точкой. Вам стоит поработать со всеми этими возможностями, чтобы получше ознакомиться с ними.

$ ./formatting

================

123456

          123456

          123456

================

123456__________

__________123456

__________123456

================

0x123abc

        0x123abc

0x        123abc

================

0123456

         0123456

         0123456

A hex number with upper case letters: 0X123ABC

A number: 0X64

Oops. now in decimal again: 100

true/false values: 1, 0

true/false values: true, false

doubles: 12.3, 12, 12.0000

scientific double: 1.230000E+11

fixed      double: 123000000000.123001

Very precise double: 0.0000000001

Less precise double: 0.0

Как это работает

Все эти stream выражения, << foo << bar, иногда довольно длинные и способны запутать читателя: ему может быть непонятно, что именно делает каждое из них. Поэтому взглянем на таблицу, в которой приведены существующие модификаторы форматов (табл. 7.1). Эти модификаторы нужно помещать в выражение input_stream >> modifier или output_stream << modifier, в этом случае они будут влиять на входные или выходные данные.

Самый лучший способ познакомиться с этими модификаторами — изучить все их многообразие и немного поработать с ними.

При взаимодействии, однако, мы уже могли заметить, что большинство модификаторов являются стойкими. Термин «стойкий» означает следующее: после применения они станут влиять на входные/выходные данные до тех пор, пока не будут сброшены. Единственные нестойкие модификаторы в табл.

1 ... 65 66 67 68 69 70 71 72 73 ... 121
Перейти на страницу:

Комментарии

Обратите внимание, что комментарий должен быть не короче 20 символов. Покажите уважение к себе и другим пользователям!

Никто еще не прокомментировал. Хотите быть первым, кто выскажется?