Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Namespace CounterNameSpace 11 страница




stream. setf (ios:: showbase);

У цьому записі елемент stream означає потік, параметри форматування якого Ви хочете змінити. Звернемо Вашу увагу на використання префікса ios:: для уточнення належності параметра showbase. Оскільки параметр showbase представляє собою перераховану константу, що визначається у класі ios, то під час звернення до неї необхідно вказувати ім'я класу ios. Цей принцип стосується всіх прапорців форматування. У наведеному нижче коді програми функція setf () використовують для встановлення прапорців showpos і scientific.

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

cout. setf (ios::showpos); // Відображ. знаку "+" перед позит. знач.

cout. setf (ios::scientific); // Відображ. чисел в експоненц. вигляді

cout << 123 << " " << 123.23 << " ";

 

getch (); return 0;

}

Ось як виглядають результати виконання цієї програми:

+123 +1.232300е+002

За допомогою операції АБО можна встановити відразу декілька потрібних прапорців форматування в одному виклику функції setf (). Наприклад, попередню програму можна скоротити, об'єднавши за допомогою АБО прапорці scientific і showpos, оскільки у цьому випадку буде виконуватися тільки одне звернення до функції setf ():

//Відображ. чисел в експоненц. вигляді або знаку "+" перед позит. знач.

cout. setf (ios:: scientific || ios:: showpos);

Щоб скинути прапорець, потрібно використовувати функцію unsetf (), прототип якої має такий вигляд:

void unsetf (fmtflags flags);

Для скидання прапорців форматування використовується функція unsetf ().

У цьому випадку будуть очищені прапорці, що задаються параметром flags. При цьому всі інші прапорці залишаються у попередньому стані.

Щоб отримати поточні установки прапорців форматування очікуваного результату, використовується функція flags ().

Для того, щоб дізнатися про поточні установки прапорців форматування, потрібно скористатися функцією flags (), прототип якої має такий вигляд:

fmtflags flags ();

Ця функція повертає поточні значення прапорців форматування для потоку, що викликається.

Під час використання наведеного нижче формату виклику функції flags () встановлюються значення прапорців форматування відповідно до вмісту параметра flags і повертаються їх попередні значення:

fmtflags flags (fmtflags flags);

Щоб зрозуміти, як працюють функції flags () і unsetf (), розглянемо детально наведену нижче програму. Вона містить функцію showflags (), яка відображає поточний стан прапорців форматування.

Код програми 19.4. Демонстрація механізму використання функцій flags() і unsetf()

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

void showflags (ios:: fmtflags f); // Відображення поточн. стану прапорців

 

int main ()

{

ios:: fmtflags f; // Оголошення параметру для пот. стану прапорців

 

f = cout. flags (); // Отримання поточного стану прапорців

showflags (f); // Відображення поточного стану прапорців

cout. setf (ios::showpos); // Відображ. знаку "+" перед позит. знач.

cout. setf (ios::scientific); //Відображ. чисел в експоненц. вигляді

 

f = cout. flags (); // Отримання поточного стану прапорців

showflags (f); // Відображення поточн. стану прапорців

// Скидання прапорця, що відображає числа в експоненц. вигляді

cout. unsetf (ios::scientific);

 

f = cout. flags (); // Отримання поточного стану прапорців

showflags (f); // Відображення поточн. стану прапорців

 

getch (); return 0;

}

 

void showflags (ios:: fmtflags f) // Відображення поточн. стану прапорців

{

long i;

 

for (i=0x4000; i; i = i >> 1)

if (i & f) cout << "1 ";

else cout << "0 ";

 

cout << "\n";

}

У процесі виконання ця програма відображає на екрані такі результати[77]:

0 0 0 0 0 1 0 0 0 0 0 0 0 0 1

0 0 1 0 0 1 0 0 0 1 0 0 0 0 1

0 0 0 0 0 1 0 0 0 1 0 0 0 0 1

У наведеному вище коді програми зверніть увагу на те, що тип fmtflags вказано з префіксом ios::. Йдеться про те, що тип fmtflags визначено у класі ios. У загальному випадку під час використання імені типу або перерахованої константи, визначеної у деякому класі, необхідно вказувати відповідне ім'я разом з іменем класу.

19.4.2. Встановлення ширини поля, точності та символів заповнення

Окрім прапорців форматування можна також встановлювати ширину поля, символ заповнення і кількість цифр після десяткової крапки (точність). Для цього достатньо використовувати такі функції:

streamsize width (streamsize len);

char fill (char ch);

 

streamsize precision (streamsize num);

1. Функція width () повертає поточну ширину поля і встановлює нову, що дорівнює значенню параметра len. Ширина поля, яка встановлюється за замовчуванням, визначається кількістю символів, необхідних для зберігання даних у кожному конкретному випадку.

2. Функція fill () повертає поточний символ заповнення (за замовчуванням використовується пропуск) і встановлює як новий поточний символ заповнення значення, які задаються параметром ch. Цей символ використовують для доповнення результату символами, яких не вистачає для досягнення заданої ширини поля.

3. Функція precision () повертає поточну кількість цифр, що відображаються після десяткової крапки, і встановлює нове поточне значення точності, що дорівнює значенню параметра num[78]|. Тип streamsize визначено як цілочисельний тип.

Розглянемо програму, яка демонструє використання цих трьох функцій.

Код програми 19.5. Демонстрація механізму використання функцій встановлення ширини поля, точності та символів заповнення

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

cout. setf (ios::showpos); // Відображ. знаку "+" перед позит. знач.

cout. setf (ios::scientific); //Відображ. чисел в експоненц. вигляді

cout << 123 << " " << 123.23 << "\n";

cout. precision (2); // Дві цифри після десяткової крапки.

cout.width (10); // Все поле складається з 10 символів.

cout << 123 << " ";

cout.width (10); // Встановлення ширини поля в 10 символів.

cout << 123.23 << "\n";

cout. fill ('#'); // Як заповнювач використаємо символ "#"

cout.width (10); // Встановлення ширини поля в 10 символів.

cout << 123 << " ";

cout.width (10) // Встановлення ширини поля в 10 символів.

cout << 123.23

 

getch (); return 0;

}

Внаслідок виконання цієї програми на моніторі буде відображено такі результати:

+123 +1.232300е+002

+123 +1.23е+002

######+123 +1.23е+002

У деяких реалізаціях С++-компілятора необхідно встановлювати значення ширини поля перед виконанням кожної операції виведення даних. Тому функція width () у попередній програмі викликалася декілька разів.

У C++-системі введення-виведення визначено і перевантажені версії функцій width (), precision () і fill (), які не змінюють поточні значення відповідних параметрів форматування і використовуються тільки для їх отримання. Ось як виглядають їх прототипи:

streamsize width() – повертає поточну ширину поля;

char fill() – повертає поточний символ заповнення;

streamsize precision() – повертає поточну кількість цифр, що відображаються після десяткової крапки

19.4.3. Використання маніпуляторів введення-виведення даних

Маніпулятори дають змогу вбудовувати настанови форматування у вираз введення-виве­дення даних.

У С++-системі введення-виведення передбачено і другий спосіб зміни параметрів форматування даних, пов'язаних з потоком. Він реалізується за допомогою спеціальних функцій – так званих маніпуляторів, які можна містити у вираз введення-виведення. Призначення та функції стандартних С++маніпуляторів введення-виведення описано в табл. 19.3.

Табл. 19.3. Стандартні С++-маніпулятори введення-виведення

Маніпулятор Призначення Функція
boolalpha Встановлює прапорець boolalpha Введення-виведення
dec Встановлює прапорець dec Введення-виведення
endl Виводить символ нового рядка і "скидає" потік, тобто переписує вміст буфера, пов'язаного з потоком, на відповідний пристрій Виведення
ends Вставляє у потік нульовий символ (' \0') Виведення
fixed Встановлює прапорець fixed Виведення
flush "Скидає" потік Виведення
hex Встановлює прапорець hex Введення-виведення
internal Встановлює прапорець internal Виведення
left Встановлює прапорець left Виведення
noboolalpha Онулює прапорець boolalpha Введення-виведення
noshowbase Онулює прапорець showbase Виведення
noshowpoint Онулює прапорець showpoint Виведення
noshowpos Онулює прапорець showpos Виведення
noskipws Онулює прапорець skipws Введення
nounitbuf Онулює прапорець unitbuf Виведення
nouppercase Онулює прапорець uppercase Виведення
oct Встановлює прапорець oct Введення-виведення
resetiosflags(fmtflags f) Онулює прапорці, що задаються у параметрі f Введення-виведення
right Встановлює прапорець right Виведення
scientific Встановлює прапорець scientific Виведення
setbase(int baseClass) Встановлює основу системи числення, що дорівнює значенню baseClass Виведення
setfill(int ch) Встановлює символ-заповнювач, що дорівнює значенню параметра ch Виведення
setiosflags(fmtflags f) Встановлює прапорці, що задаються у параметрі f Введення-виведення
setprecision(int p) Встановлює кількість цифр точності (після десяткової крапки), що дорівнює значенню параметра p Виведення
setw(int w) Встановлює ширину поля, що дорівнює значенню параметра w Виведення
showbase Встановлює прапорець showbase Виведення
showpoint Встановлює прапорець showpoint Виведення
showpos Встановлює прапорець showpos Виведення
skipws Встановлює прапорець skipws Введення
unitbuf Встановлює прапорець unitbuf Виведення
uppercase Встановлює прапорець uppercase Виведення
ws Пропускає провідні "пропускні" символи Введення

У процесі використання маніпуляторів, які приймають аргументи, необхідно приєднати до програми заголовок < iomanip >.

Будь-який маніпулятор використовується як частина виразу введення-виведення. Нижче наведено приклад програми, у якій показано, як за допомогою маніпуляторів можна керувати процесом форматування даних, що виводяться.

Код програми 19.6. Демонстрація механізму використання маніпуляторів для керування процесом форматування даних, що виводяться

#include <iostream> // Для потокового введення-виведення

#include < iomanip >

using namespace std; // Використання стандартного простору імен

 

int main ()

{

cout << setprecision (2) << 1000.243 << endl;

cout << setw (20) << "Всім привіт! ";

 

getch (); return 0;

}

Результати виконання цієї програми є такими:

1е+003

Всім привіт!

Зверніть увагу на те, як використовуються маніпулятори у послідовності операцій введення-виведення даних. Окрім того, зверніть увагу також на те, коли маніпулятор викликається без аргументів (як, наприклад, маніпулятор endl у наведеному вище коді програми), то його ім'я вказується без пари круглих дужок.

У наведеному нижче коді програми використовується маніпулятор setiosflags () для встановлення прапорців scientific і showpos.

Код програми 19.7. Демонстрація механізму використання маніпулятора setiosflags() для встановлення прапорців scientific і showpos

#include <iostream> // Для потокового введення-виведення

#include < iomanip >

using namespace std; // Використання стандартного простору імен

 

int main ()

{

// Відображення знаку "+" перед позитивним значенням числа

cout << setiosflags (ios::showpos);

// Відображення чисел в експоненціальному вигляді

cout << setiosflags (ios::scientific);

cout << 123 << " " << 123.23;

 

getch (); return 0;

}

Результати виконання цієї програми є такими:

+123 +1.232300е+002

А у цій програмі продемонстровано механізм використання маніпулятора ws, який пропускає провідні "пропускні" символи під час введення рядка в масив sMas.

Код програми 19.8. Демонстрація механізму використання маніпулятора ws, який пропускає провідні "пропускні" символи

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

char sMas[80];

cin >> ws >> sMas;

cout << sMas;

 

getch (); return 0;

}

19.4.4. Створення власних маніпуляторних функцій

Програміст може самостійно створювати власні маніпуляторні функції. Існує два типи маніпуляторних функцій – ті, що приймають (параметризовані) і не приймають аргументи (непараметризовані). Для створення параметризованих маніпуляторів використовуються підходи, вивчення яких виходить за рамки цього навчального посібника. Проте створення непараметризованих маніпуляторів не викликає особливих труднощів.

Всі непараметризовані маніпуляторні функції виведення даних мають таку структуру:

ostream & manip_name (ostream & stream)

{

// код маніпуляторної функції

return stream; // Повертає посилання на параметр stream

}

У цьому записі елемент manip_name вказує ім'я маніпулятора. Важливо розуміти особливості використання не параметризованих маніпуляторів. Незважаючи на те, що маніпулятор приймає як єдиний аргумент покажчик на потік, який він обробляє, проте під час використання маніпулятора в остаточному виразі введення-виведення аргументи не вказуються взагалі.

У наведеному нижче коді програми створюється маніпулятор setup (), який встановлює прапорець вирівнювання по лівому краю, ширину поля в 10 символів і задає як заповнювальний символ знак долара.

Код програми 19.9. Демонстрація створення маніпулятора setup()

#include <iostream> // Для потокового введення-виведення

#include < iomanip >

using namespace std; // Використання стандартного простору імен

 

ostream & setup (ostream & stream)

{

stream. setf (ios:: left); // Вирівнювання по лівому краю

 

/* Встановлює ширину поля в 10 символів і задає як заповнювальний

символ знак долара */

stream << setw (10) << setfill ('$');

 

return stream; // Повертає посилання на параметр stream

}

 

int main ()

{

cout << 10 << " " << setup << 10;

getch (); return 0;

}

Створення власних маніпуляторів є корисним з двох причин:

по-перше, іноді виникає потреба виконувати операції введення-виведення даних з використанням пристрою, до якого жоден з вбудованих маніпуляторів не застосовується (наприклад, плоттер). У цьому випадку створення власних маніпуляторів зробить виведення даних на цей пристрій зручнішим;

по-друге, може так статися, що у створеній Вами програмі деяка послідовність настанов повторюється декілька разів. І тоді ці операції можна об'єднати в один маніпулятор так, як це показано у попередній програмі.

Всі непараметризовані маніпуляторні функції введення даних мають таку структуру:

istream & manip_name (istream & stream)

{

// код маніпуляторної функції

return stream; // Повертає посилання на параметр stream

}

Наприклад, у наведеному нижче коді програми створюється маніпулятор prompt (). Він налаштовує вхідний потік на прийняття даних у шістнадцятковому представленні та виводить для користувача відповідне повідомлення.

Код програми 19.10. Демонстрація створення маніпулятора prompt()

#include <iostream> // Для потокового введення-виведення

#include < iomanip >

using namespace std; // Використання стандартного простору імен

 

istream & prompt (istream & stream)

{

cin >> hex;

cout << "Введіть число в шістнадцятковому форматі: ";

 

return stream; // Повертає посилання на параметр stream

}

 

int main ()

{

int izm;

cin >> prompt >> izm;

cout << izm; // Виведення числа в шістнадцятковому форматі

 

getch (); return 0;

}

Необхідно пам'ятати! Надзвичайно важливо, щоб створений програмістом маніпулятор повертав потоковий об'єкт (елемент stream). Інакше цей маніпулятор не можна буде використовувати у складеному виразі введення або виведення.

19.5. Файлове введення-виведення даних

У С++-системі введення-виведення також передбачено засоби для виконання відповідних операцій з використанням файлів. Файлові операції введення-виведення даних можна реалізувати після внесення у програму заголовка < fstream >, у якому визначено всі необхідні для цього класи і значення.

19.5.1. Відкриття та закриття файлу

У мові програмування C++ файл відкривається шляхом зв'язування його з потоком. Як уже зазначалося вище, існують потоки трьох типів: введення, виведення і введення-виведення. Щоб відкрити вхідний потік, необхідно оголосити потік класу ifstream. Для відкриття вихідного потоку потрібно оголосити потік класу ofstream. Потік, який передбачається використовувати для операцій як введення, так і виведення, повинен бути оголошений як потік класу fstream. Наприклад, у процесі виконання такого фрагмента коду програми буде створено вхідний і вихідний потоки, а також потік, що дає змогу виконувати операції в обох напрямах:

ifstream in; // Вхідний потік

ofstream out; // Вихідний потік

fstream both; // Потік введення-виведення

Щоб відкрити файл, використовується функція open ().

Створивши потік, його потрібно пов'язати з файлом. Це можна зробити за допомогою функції open (), причому у кожному з трьох потокових класів є своя функція-член open (). Їх прототипи мають такий вигляд:

void ifstream:: open (const char * filename,

ios:: openmode mode = ios:: in);

void ofstream:: open (const char * filename,

ios:: openmode mode = ios:: out | ios:: trunc);

void fstream:: open (const char * filename,

ios:: openmode mode = ios:: in | ios:: out);

У цих записах елемент filename означає ім'я файлу, яке може містити специфікатор шляху, який вказує доступ до нього. Елемент mode називається специфікатором режиму, який визначає спосіб відкриття файлу. Він повинен приймати одне або декілька значень перерахунку openmode, який визначено у класі ios:

ios::арр – приєднує до кінця файлу усі дані, що виводяться;

ios::ate – пошук потрібних даних починатиметься з кінця файлу;

ios::binary – відкриває файл у двійковому режимі;

ios::in – забезпечує відкриття файлу для введення даних;

ios::out – забезпечує відкриття файлу для виведення даних

ios::trunc – призводить до руйнування вмісту файлу.

Декілька значень перерахунку openmode можна об'єднувати за допомогою логічного додавання (АБО).

Варто знати! Параметр mode для функції fstream:: open ()за замовчуванням може не дорівнювати значенню in | out (це залежить від використовуваного компілятора). Тому у разі потреби цей параметр Вам доведеться задавати в безпосередньому вигляді.

Необхідно пам'ятати! За замовчуванням усі файли відкриваються в текстовому режимі.

1. Внесення значення ios:: арр у параметр mode забезпечить приєднання до кінця файлу всіх даних, що виводяться. Це значення можна застосовувати тільки до файлів, відкритих для виведення даних.

2. Під час відкриття файлу з використанням значення ios:: ate пошук потрібних даних починатиметься з кінця файлу. Незважаючи на це, операції введення-виведення даних можуть, як і раніше, виконуватися по всьому файлу.

3. Значення ios:: binary дає змогу відкрити файл у двійковому режимі. Як ми вже зазначали вище, в текстовому режимі можуть відбуватися деякі перетворення символів (наприклад, послідовність, що складається з символів повернення каретки і переходу на новий рядок, може бути перетворена у символ нового рядка). Під час відкриття файлу у двійковому режимі ніякого перетворення символів не виконується.

4. Значення ios:: in вказує на те, що даний файл відкривається для введення даних, а значення ios:: out забезпечує відкриття файлу для виведення даних.

5. Використання значення ios:: trunc призводить до руйнування вмісту файлу, ім'я якого збігається з параметром filename, а сам цей файл урізається до нульової довжини. Під час створення вихідного потоку типу ofstream будь-який наявний файл з іменем filename автоматично урізається до нульової довжини.

Варто знати! Будь-який файл, що містить форматований текст або ще необроблені дані, можна відкрити як у двійковому, так і в текстовому режимі. Єдина відмінність між цими режимами полягає у перетворенні (чи ні) символів.

У процесі виконання такий фрагмент коду програми відкриває звичайний вихідний файл:

ofstream out;

out. open ("тест");

Оскільки параметру mode функції open () за замовчуванням встановлюється значення, що дорівнює відповідному типу потоку, який відкривається, то у попередньому прикладі взагалі немає потреби задавати його значення.

У результаті невдалого виконання функції open ()не відкритому потоку під час використання булевого виразу встановлюється значення, що дорівнює ФАЛЬШ. Цей факт може слугувати для підтвердження успішного відкриття файлу, наприклад, за допомогою такої if -настанови:

if (!myStream) {

cout << "Hе вдається відкрити файл.\n";

// оброблення помилки

}

Необхідно пам'ятати! Перш ніж робити спробу отримання доступу до даних файлу, необхідно завжди перевіряти результат виклику функції open ().




Поделиться с друзьями:


Дата добавления: 2014-11-29; Просмотров: 548; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.12 сек.