Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Файловые и строковые потоки






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

Классы потоков ввода-вывода (они называются istream, ostream и iostream для входных, выходных и комбинированных потоков, соответственно) служат базовыми для создания файловых (ifstream, ofstream, fstream) и строковых потоков (istringstream, ostringstream, stringstream). И для того, чтобы начать пользоваться этими новыми видами потоков, достаточно освоить всего несколько новых операций - открытие и закрытие, и, в случае ostringstream, преобразование потока в строку.

Если помните, в начале занятия класс Complex с операторами ввода-вывода. Так вот, эти же операторы прекрасно будут работать и с файлами

ifstream ifs(" my_numbers.dat");
ofstream ofs(" my_results.out");
Complex c;
ifs > > c;

ofs < < c < < endl;

// Явное закрытие потоков нужно лишь на случай
// аварийного завершения программы.
// При нормальном завершении файлы закроются
// при вызове деструкторов
ifs.close();
ofs.close();

и с символьными массивами

char buf[1024];
...;

// Связываем входной строковый поток с массивом buf
istringstream is(buf);

ostringstream os;

Complex c;
// Считываем значение
is > > c;

// Выводим значение в строковый поток
os < < c < < ends;

// Выводим накопленное содержимое строкового потока
// в cout
// Функция str() возвращает содержимое строкового потока
// в виде строки
cout < < os.str();

 

Разумеется, в этом примере не приведены некоторые детали реализации, специфичные для работы с файлами и строками (например, файл можно открывать в разных режимах, можно позиционировать указатель записи-чтения в файле и т.п.). Но для многих задач эти детали попросту не нужны - потоки, открываемые с параметрами по умолчанию, обеспечивают вполне разумное поведение, и, раз открыв поток, вы уже можете не особенно задумываться, с чем именно вы работаете - с файлом, массивом или чем-то еще.

 

Возможность управлять вводом-выводом в С++, обеспечивают форматирующие функции-члены, флаги и манипуляторы. Флаги, функции и манипуляторы выполняют одну и туже задачу — задают определённый формат ввода/вывода информации в потоках. Ввод/вывод на экран/с экрана в С++ осуществляется с помощью операторов cin и cout соответственно, а значит манипуляторы форматирования используются совместно с данными операторами ввода/вывода. Различие между функциями флагами и манипуляторами форматирования состоит в способе их применения. Теперь рассмотрим способы применения объектов форматирования.

  //Основные форматирующие функции-члены: cout.fill('/*symbol*/'); // устанавливает символ заполнитель // где symbol - символ заполнитель, символ передаётся в одинарных кавычках   cout.width(/*width_field*/); // задает ширину поля // где width_field - количество позиций(одна позиция вмещает один символ)   cout.precision(/*number*/); // задает количество знаков после десятичной точки // где number - количество знаков после десятичной точки

Доступ к функциям осуществляется через операцию точка, а в круглых скобочках передаётся аргумент. Аргумент функции fill()может передаваться в виде символа, обрамленного одинарными кавычками, или в виде числа(код символа). Одних функций не достаточно для форматирования потоков ввода/вывода, поэтому в С++ предусмотрен ещё один способ форматирования — флаги.

Флаги форматирования позволяют включить или выключить один из параметров ввода/вывода. Чтобы установить флаг ввода/вывода, необходимо вызвать функцию setf(), если необходимо отключить флаг вывода, то используется функция unsetf(). Далее показаны конструкции установки и снятия флагов вывода.

  // установка флага вывода cout.setf(ios:: /*name_flag*/); // где name_flag - это имя флага

Доступ к функциям оператора вывода выполняется через операцию точка. Метод setf()принимает один аргумент — имя флага. Флаги вывода объявлены в классе ios, поэтому, перед тем, как обратиться к флагу, необходимо написать имя класса — ios, после которого, с помощью операции разрешения области действия, вызвать нужный флаг.

  // снятие флага вывода cout.unsetf(ios:: /*name_flag*/); // где name_flag - это имя флага

Если при вводе/выводе необходимо установить(снять) несколько флагов, то можно воспользоваться поразрядной логической операцией ИЛИ |. В этом случае конструкция языка C++ будет такой:

  // установка нескольких флагов cout.setf(ios:: /*name_flag1*/ | ios:: /*name_flag2*/ | ios:: /*name_flag_n*/);   // снятие нескольких флагов cout.unsetf(ios:: /*name_flag1*/ | ios:: /*name_flag2*/ | ios:: /*name_flag_n*/);

В таблице 1 подробно описаны основные флаги форматирования, а также показаны примеры использования флагов.

Таблица 1 — Флаги форматирования в С++  
Флаг Назначение Пример Результат
boolalpha Вывод логических величин в текстовом виде (true, false) cout.setf(ios:: boolalpha); bool log_false = 0, log_true = 1; cout < < log_false < < endl < < log_true < < endl; false true
oct Ввод/вывод величин в восьмеричной системе счисления (сначала снимаем флаг dec, затем устанавливаем флаг oct) cout.unsetf(ios:: dec); cout.setf(ios:: oct); int value; cin > > value; cout < < value < < endl; ввод: 9910 вывод: 1438
dec Ввод/вывод величин в десятичной системе счисления (флаг установлен по умолчанию) cout.setf(ios:: dec); int value = 148; cout < < value < < endl;  
hex Ввод/вывод величин в шестнадцатеричной системе счисления (сначала снимаем флаг dec, затем устанавливаем флаг hex) cout.unsetf(ios:: dec); cout.setf(ios:: hex); int value; cin > > value; cout < < value < < endl; ввод: 9910 вывод: 6316
showbase Выводить индикатор основания системы счисления cout.unsetf(ios:: dec); cout.setf(ios:: oct | ios:: showbase); int value; cin > > value; cout < < value < < endl; ввод: 9910 вывод: 01438
uppercase В шестнадцатеричной системе счисления использовать буквы верхнего регистра(по умолчанию установлены буквы нижнего регистра) cout.unsetf(ios:: dec); cout.setf(ios:: hex | ios:: uppercase); int value; cin > > value; cout < < value < < endl; ввод: 25510 вывод: FF16
showpos Вывод знака плюс + для положительных чисел cout.setf(ios:: showpos); int value = 15; cout < < value < < endl; +15
scientific Вывод чисел с плавающей точкой в экспоненциальной форме cout.setf(ios:: scientific); double value = 1024.165; cout < < value < < endl; 1.024165e+003
fixed Вывод чисел с плавающей точкой в фиксированной форме(по умолчанию) double value = 1024.165; cout < < value < < endl; 1024.165
right Выравнивание по правой границе(по умолчанию). Сначала необходимо установить ширину поля(ширина поля должна быть заведомо большей чем, длина выводимой строки). cout.width(40); cout < < «cppstudio.com» < < endl; __cppstudio.com
left Выравнивание по левой границе. Сначала необходимо установить ширину поля(ширина поля должна быть заведомо большей чем, длина выводимой строки). cout.setf(ios:: left); cout.width(40); cout < < «cppstudio.com» < < endl; cppstudio.com__

Ещё один способ форматирования — форматирование с помощью манипуляторов. Манипулятор — объект особого типа, который управляет потоками ввода/вывода, для форматирования передаваемой в потоки информации. Отчасти манипуляторы дополняют функционал, для форматирования ввода/вывода. Но большинство манипуляторов выполняют точно, то же самое, что и функции с флагами форматирования. Есть случаи, когда проще пользоваться флагами или функциями форматирования, а иногда удобнее использовать манипуляторы форматирования. Именно по этому в С++ предусмотрено несколько средств форматирования ввода/вывода. В таблице 2 показаны основные манипуляторы форматирования С++.

Таблица 2 — Манипуляторы форматирования в С++
Манипулятор Назначение Пример Результат
endl Переход на новую строку при выводе cout < < «website:» < < endl < < «cppstudio.com»; website: cppstudio.com
boolalpha Вывод логических величин в текстовом виде (true, false) bool log_true = 1; cout < < boolalpha < < log_true < < endl; true
noboolalpha Вывод логических величин в числовом виде (true, false) bool log_true = true; cout < < noboolalpha < < log_true < < endl;  
oct Вывод величин в восьмеричной системе счисления int value = 64; cout < < oct < < value < < endl; 1008
dec Вывод величин в десятичной системе счисления (по умолчанию) int value = 64; cout < < dec < < value < < endl; 6410
hex Вывод величин в шестнадцатеричной системе счисления int value = 64; cout < < hex < < value < < endl; 408
showbase Выводить индикатор основания системы счисления int value = 64; cout < < showbase < < hex < < value < < endl; 0x40
noshowbase Не выводить индикатор основания системы счисления (по умолчанию). int value = 64; cout < < noshowbase < < hex < < value < < endl;  
uppercase В шестнадцатеричной системе счисления использовать буквы верхнего регистра (по умолчанию установлены буквы нижнего регистра). int value = 255; cout < < uppercase < < hex < < value < < endl; FF16
nouppercase В шестнадцатеричной системе счисления использовать буквы нижнего регистра (по умолчанию). int value = 255; cout < < nouppercase < < hex < < value < < endl; ff16
showpos Вывод знака плюс + для положительных чисел int value = 255; cout < < showpos< < value < < endl; +255
noshowpos Не выводить знак плюс + для положительных чисел (по умолчанию). int value = 255; cout < < noshowpos< < value < < endl;  
scientific Вывод чисел с плавающей точкой в экспоненциальной форме double value = 1024.165; cout < < scientific < < value < < endl; 1.024165e+003
fixed Вывод чисел с плавающей точкой в фиксированной форме (по умолчанию). double value = 1024.165; cout < < fixed < < value < < endl; 1024.165
setw(int number) Установить ширину поля, где number — количество позиций, символов (выравнивание по умолчанию по правой границе). Манипулятор с параметром. cout < < setw(40) < < «cppstudio.com» < < endl; __cppstudio.com
right Выравнивание по правой границе(по умолчанию). Сначала необходимо установить ширину поля(ширина поля должна быть заведомо большей чем, длина выводимой строки). cout < < setw(40) < < right < < «cppstudio.com» < < endl; __cppstudio.com
left Выравнивание по левой границе. Сначала необходимо установить ширину поля(ширина поля должна быть заведомо большей чем, длина выводимой строки). cout < < setw(40) < < left < < «cppstudio.com» < < endl; cppstudio.com__
setprecision(int count) Задаёт количество знаков после запятой, где count — количество знаков после десятичной точки cout < < fixed < < setprecision(3) < < (13.5 / 2) < < endl; 6.750
setfill(int symbol) Установить символ заполнитель. Если ширина поля больше, чем выводимая величина, то свободные места поля будут наполняться символом symbol— символ заполнитель cout < < setfill(‘0′) < < setw(4) < < 15 < < ends < < endl;  

Форматированный ввод/вывод в С++ это одна из самых простых тем в программировании. Как использовать те или иные средства форматирования показано в таблицах, поэтому затруднений по данной теме возникнуть не должно.

 

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.