Форматирование ввода/вывода в С++

В С++ информацию можно вводить и выводить в широком диапазоне форм. Можно изменять определённые параметры ввода и вывода  информации. Каждый поток (cin и cout) имеет набор флагов формата (format flags), которые предназначены для управления форматированием информации и представляют собой битовые маски(bitmasks), т.е каждый флаг занимает один бит. Стандартная библиотека  ввода/вывода С++ (Standard C++) создаёт два класса шаблона: одна для 8-ми битных символов, а другая для 16-ти битных символов. К 16-ти разрядным относятся символы уникода, каждый из которых хранится в 2-х байтах. Здесь речь пойдёт о 8-ми разрядных потоках, так как они используются чаще всего. К ним относятся потоки: cout, cin, cerr, clog. Да, в отличии от языка С (stdout, stdin, stderr) в С++ открываются целых четыре потока. Битовые маски объявлены в классе ios (производный от класса basic_ios) как данные типа fmtflags (аналогичен типу long). Вот список флагов: 

  • ·         adjustfield (ставит флаги left, right и internal)
  • ·         basefield (ставит флаги oct,dec и hex)
  • ·         boolalpha (данные типа bool выводятся в виде “true” и “false”)
  • ·         dec (вывод в десятичной системе счисления, установлен по умолчанию)
  • ·         fixed (вещественные числа выводятся в обычной форме)
  • ·         floatfield (ставит флаги scientific и fixed)
  • ·         hex (вывод в шестнадцатеричной системе счисления)
  • ·         internal (для заполнения поля вставляется пробел между цифрами)
  • ·         left (выравнивание по левому краю)
  • ·         oct (вывод в восьмеричной системе счисления)
  • ·         right (выравнивание по правому краю)
  • ·         scientific (вывод вещественных чисел с использованием “E”)
  • ·         showbase (показывает основание типа системы счисления)
  • ·         showpoint (показывает десятичную точку и последующие нули для вещественных чисел)
  • ·         showpos (показывает знак “+” перед положительными числами)
  • ·         skipws (отбрасываются невидимые символы(пробел, перенос строки, табуляция))
  • ·         unitbuf (освобождает буфер)
  • ·         uppercase  (переводит регистр в верхний уровень)  
  
Внутри класса ios имеются три функции для работы с вышеперечисленными флагами: setf(), unsetf(), flag().  Теперь по порядку об использовании этих функций.
Функция setf() устанавливает флаг, который передаётся в функцию как параметр. Объявлена эта функция следующим следующим образом:
fmtflags setf (fmtflags flag);
Здесь вместо “flag” нужно подставить флаг который надо установить. НО! Флаги являются членами класса ios и просто к ним не обратиться. Поэтому надо использовать оператор глобального разрешения
“::”. Например: ios::showbase. Возвращает функция старое значение переданного в параметре флага. Важно понять, что установив тот или иной флаг он будет распространяться на каждый поток создаваемый этим классом, то есть на потоки cout и cin.  Пример использования:
cout.setf (ios::hex);
Функция unsetf() предназначена для снятия флажка. Объявлена так:
void unsetf (fmtflags flag);
Как видно функция ничего не возвращает. Пример использования:
 
cout.unsetf(ios::dec);
 При использовании функций setf и unsetf в качестве параметра можно передавать несколько флагов. Для этого достаточно разделять их оператором побитового ИЛИ. Например:
cout.setf (ios::showpos | ios::showpoint | ios::hex);
cout.unsetf (ios::showpos | ios::showpoint | ios::hex);
Приведу пример с использованием обеих функций.

 #include "stdafx.h"
 #include "iostream"
 #include
 using namespace std;
  
 void main ()
 {
       cout<<-10<<' '<<10<<' '<<123.4<<"\n\n";
       cout.setf (ios::showpoint | ios::showpos | ios::scientific);
       cout<<-10<<' '<<10<<' '<<123.4<<"\n\n";
       cout.unsetf(ios::showpoint | ios::showpos | ios::scientific);
       cout<<-10<<' '<<10<<' '<<123.4<<"\n\n";
       _getch();
 }

И наконец последняя функция flags(). Объявлена она следующим образом:
fmtflags flags (fmtflags flags);
Эту функцию можно использовать двояко. Первый способ это получение информации о всех полях. Пример:
ios::fmtflags OldFlags;
OldFlags=cout.flags ();
Второй способ заключается в том, что с помощью этой функции можно установить все флажки формата. Для этого функции нужно передать переменную с информацией о всех полях. При этом предыдущие поля перезаписываются на новые. Пример:
cout.flags(OldFlags);
В качестве примера простая программа:

 #include "stdafx.h"
 #include
 #include
 using namespace std;
 void main()
 {
        cout<<-10<<' '<<10<<' '<<123.4<<"\n\n";
        ios::fmtflags OldFlags;
        OldFlags=cout.flags();
        cout.setf (ios::showpoint | ios::showpos | ios::scientific);
        cout<<-10<<' '<<10<<' '<<123.4<<"\n\n";

        cout.flags(OldFlags);
        cout<<-10<<' '<<10<<' '<<123.4<<"\n\n";
        _getch();
 } 

Если будете практиковаться с флажками формата, то очень кстати придётся вот эта функция:

 void showflags()
 {
     ios::fmtflags flags;
     flags=cout.flags();
     if (flags & ios::skipws) cout<< "skipws enable\n";
     else cout<< "skipws disable\n";
     if(flags & ios::left) cout << "left enable\n";
     else cout << "left disable\n";

     if(flags & ios::right) cout << "right enable\n";
     else cout << "right disable\n";

     if(flags & ios::internal) cout << "internal enable\n";
     else cout << "internal disable\n";
     if(flags & ios::dec) cout << "dec enable\n";
     else cout << "dec disable\n";
     if(flags & ios::oct) cout << "oct enable\n";
     else cout << "oct disable\n";
     if(flags & ios::hex) cout << "hex enable\n";
     else cout << "hex disable\n";
     if(flags & ios::showbase) cout << "showbase enable\n";
     else cout << "showbase disable\n";

     if(flags & ios::showpoint) cout << "showpoint enable\n";
     else cout << "showpoint disable\n";

     if(flags & ios::showpos) cout << "showpos enable\n";
     else cout << "showpos disable\n";

     if(flags & ios::uppercase) cout << "uppercase enable\n";
     else cout << "uppercase disable\n";

     if(flags & ios::scientific) cout << "scientific enable\n";
     else cout << "scientific disable\n";

     if(flags & ios::fixed) cout << "fixed enable\n";
     else cout << "fixed disable\n";

     if(flags & ios::unitbuf) cout << "unitbuf enable\n";
     else cout << "unitbuf disable\n";

     if(flags & ios::boolalpha) cout << "boolalpha enable\n";
     else cout << "boolalpha disable\n";

    cout << "\n";
}

Она выводит информацию о полях.