Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

osn_progr_final

.pdf
Скачиваний:
37
Добавлен:
12.02.2016
Размер:
3.27 Mб
Скачать

char ios::fill(); - повертає бiжучий символ заповнення.

char ios::fill(char); - встановлює внутрiшнiй заповнюючий символ потоку i повертає його попереднє значення.

Cимволом заповнення по замовчуванню є пропуск. Приклад (встановлення заповнюючого символа ‘\0’):

const char FILL_CHAR=‘\0’; cout.fill(FILL_CHAR); cout.width(10);

int x=2867; cout<<x<<‘\n’;

1.5.3 Кількість цифр дійсних чисел

Функцiї ios::precision можуть використовуватись при виводi чисел з плаваючою крапкою, дозволяючи читати або встановлювати бiжуче число значущих цифр.

int ios::precision(int); -встановлює внутрiшню змiнну точностi дiйсних чисел потоку i повертає попереднє значення.

int ios::precision(); - повертає бiжуче значення точностi.

По замовчанню точнiсть дорівнює 6 цифрам.

Якщо встановлений прапопець scientific або fixed, precision задає число цифр, що виводяться пiсля десяткової крапки.

Якщо не встановлено нi один з прапорцiв scientific або fixed, precision задає загальне число значущих цифр. Приклад:

#include<iostream.h> int main(void)

{ float f=3456.141592; double d=50.2345639101; cout.precision(4); cout<<d<<‘\n’; cout<<f<<‘\n’; cout<<f<<‘\n’;

return 0;}

1.5.4Прапорці форматування

Впотоках C++ допускається використовувати прапорцi формату. Вони задають, яким чином форматується ввiд/вивiд. Прапорцi являються бiтовими полями, що зберiгаються в змiннiй типу long (див.

клас ios).

Прапорцi формату ios:

ios::skipws -якщо встановлений, то при вводi iгноруються пропуски. Встановлений по замовчанню;

341

ios::left -вирiвнювання даних по лiвiй границi поля, по замовчіванню не встановлений;

ios::right -вирiвнювання даних по правiй границi поля, встановлений по замовчуванню;

ios::internal лiвого краю поля виводиться знак чмсла; число вирiвнюється по правому краю, промiжки заповнюються символами fill;

ios::dec -якщо встановлений,то числа виводяться з основою

10;

ios::oct -якщо встановлений,то числа виводяться з основою 8;

ios::hex -якщо встановлений,то числа виводяться з основою

16;

ios::showbase -якщо встановлений,то добавляється iндикатор з основою("0x"для 16-ткових i "0" для вiсiмкових);

ios::uppercase -якщо встановлений,то букви вiд A до F в 16кових числах виводяться в верхньому регiстрi.Експонента Е в науковiй нотацiї чисел також виводиться в верхньому регiстрi;

ios::showpoint -якщо встановлений, при виводi чисел типу float,double i long double показується десяткова крапка;

ios::showpos -якщо встановлений, то виводиться знак + для додатнього числа;

ios::scientific -дiйснi числа вводяться в науковiй нотацi·:1.2 e 2;

ios::fixed -числа вводяться у формi з фiксованою крап-

кою:1.567;

ios::unitbuf -буфер потоку звiльняється пiсля кожної операцiї помiщення;

ios::stdio -якщо встановлений, потоки stdout i strerr звiльняються пiсля кожної операцiї помiщення.

Прапорці ios::left , ios::right та ios::internal взаємно виключають

один одного. Прапорці ios::dec , ios::oct та ios::hex також взаємно виключають один одного. При модифікації основи можна використати константу ios::basefield в якості другого параметра функції setf. При заданні способу вирівнювання можна використовувати константу ios::ajustfield в якості другого параметра функції setf. При заданні нотації дійсних чисел можна використовувати константу ios::floatfield в якості другого параметра функції setf.

Методи управлiння прапорцями

342

long ios::flags(); - повертає бiжучi прапорцi потоку;

long ios::flags(long); - встановлює значення прапорцiв вiдповiдно до значення, яке є параметром функцiї; повертає попереднiй стан;

long ios::setf(long,long); присвоює прапорцям, бiти яких встановленi в другому параметрi, значення вiдповiдних бiт першого параметра.Повертає попередні значення всiх прапорцiв;

long ios::setf(long); встановлює прапорцi, бiти яких ненульовi в параметрi;

long ios::unsetf(long); скидає прапорцi, бiти яких встановленi в параметрi.

Приклад1(iгнорування пропускiв при вводi): int i=0;

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

cin >>i;

//видаляються символи, що залишились в потоці cin.ignore(INT_MAX,’\n’);

//скидається прапорець skipws cin.unsetf(ios::skipws);

//а ця операція вже не ігнорує пропуски

cin >>i;

//перевіряє наявність пропусків чи інших недопустимих символів

cin.good()? (cout<<'ви ввели'<<i<<endl): (cout <<'неправильний ввiд'<<endl);

Приклад 2:

int x=1678; cout <<x;

//зберігається значення прапорців long savedFlags=cout.flags;

//встановити основу 16 з індикацією cout.setf (ios::showbase|ios::hex); cout <<x;

Приклад 3:

float f=2.3456789e6; double d=3.0e9; cout<<f<<‘\n’; cout<<d<<‘\n’;

//вводити знак + для додатних значень cout.setf(ios::showpos); cout<<f<<‘\n’;

cout<<d<<‘\n’;

343

1.5.5 МАНІПУЛЯТОРИ

Манiпулятори - це функцiї, якi можна включати в послiдовнiсть операцiй вводу/виводу. Iснує два типи манiпуляторiв - з параметрами та без параметрiв.

Манiпулятори без параметрiв(простi):

endl - помiщує в потiк символ переводу рядка;

ends - помiщує в вихiдний потiк нулевий символ(\0);

flush - примусово записує всi вихiднi данi на вiдповiднi фiзичнi пристрої;

dec - встановлює основу числа; hex - встановлює основу числа; oct -встановлює основу числа;

ws заставляє iгнгорувати при вводi пробiлові символи.

Приклад: int i;

cin>>i;

if(!cin) cout<<“помилковий ввід”<<endl; else{

cout<<"вивести в рiзних системах числення"; cout <<'hex:'<<hex<<i<<endl

<<'oct:'<<oct<<i<<endl

<<'dec:'<<dec<<i<<endl;}

Параметризованi манiпулятори

1.setbase(int_b); задає основу(по замовчанню 10) 2.resetiosflags(long_b); -скидає прапорцi, бiти яких встановленi в переданому параметрi;

3.setiosflags(long_b); встановлює прапорцi бiти яких встановленi в переданому параметрi;

4.setfill(int_f); задає заповнюючий символ;

5.setprecision(int_n); задає значення внутрiшньої змiнної точностi дійсних чисел;

6.setw(int_w); задає значення внутрiшньої змiнної ширини поля. Приклад:

double dbls[ ]={'.245,-12.99133}; cout <<setfill('.')

<<setprecision(4) //12.9913 <<setiosflags(ios::showpoint;

ios::fixed;

ios::right); for (int i=0;i<2;i++)

cout <<setw(20)<<dbls[i]<<endl.

344

1.6 СТАН ПОТОКУ

Iснують рiзнi функцiї та операцiї, що дозволяють читати стан потоку, а також функцiї для установки чи очистки стану.

int rdstate(); - повертає бiжучий стан;

int eof(); -повертає ненульове значення, якщо встановлений прапо-

рець eofbit;

int fail(); - повертає ненульове значення, якщо встановлений один з прапорцiв failbit,badbit,hardfail;

int bad(); - повертає ненульове значення, якщо встановлений прапо-

рець badbit або hardfail;

int good(); - повертає ненульове значення, якщо скинутi всi бiти помилок;

void clear(int=0); якщо параметр дорiвнює 0 (по замовчанню ), всi бiти очи -щаються. В противному випадку параметр приймається в якостi стану помилки;

operаtor void*(); - повертає нульовий вказівник, якщо встановлений один з бітів failbit,badbit,hardfail;

int operator!(); - повертає ненульове значення, якщо встановлений один з бітів failbit,badbit,hardfail;

Відмітимо, що операція void*() неявно викликається завжди, коли потік порівнюється з нулем. Тому можна писати вирази виду: while(srtmObj)

{// з потоком все впорядку, можемо проводити операції вводувиводу}

Дiї над станами потоку

1.if(strm.rdstate() & ios::flag) - перевiряє чи встановлений flag 2.strm.clear(rdstate() & ~ios::flag) -скинути flag 3.strm.clear(rdstate() | ios::flag ) - встановити flag

4.strm.clear(ios::flag) - встановити flag (скидає iншi прапорцi) 5.strm.clear() - скидає всi прапорцi.

1.7 ФАЙЛОВИЙ ВВІД-ВИВІД

Бiблiотека С++ має три спецiалiзованих класи для файлового

вводу/виводу:

 

ifstream:

для операцiй з вхiдним дисковим фацлом.

ofstream:

для операцiй з вихiдним дисковим файлом.

fstream: для вхiдних i вихiдних операцiй з файлом.

Вказанi класи

є похiдними вiд класів вiдповiдно

 

345

istream,ostream,iostream (див. мал. 1). Тому вони унаслiдують всi їх особливостi (манiпулятори, прапорцi, перевантаженi оператори).

1.7.1 КОНСТРУКТОРИ ФАЙЛОВИХ ПОТОКIВ

Для кожного з перерахованих вище класiв передбачено 4 конструктори. Вони дозволяють робити слiдуюче:

Конструювати об'єкт, не вiдкриваючи файлу: ifstream();

ofstream();

fstream;

Конструювати об'єкт, вiдкрити файл i прикрiпити об'єкт до файлу: ifstream(const char *name,

int omode=ios::in,

int prot=filebuf::openprot); ofstream(const char *name,

int omode=ios::out,

int prot=filebuf::openprot); fstream(const char *name,

int omode,

int prot=filebuf::openprot);

Зконструювати об'єкт i прикрiпити його до вже вiдкритого файлу. При цьому вказується дескриптор файлу:

ifstream(int f); ofstream(int f); fstream(int f);

Конструювати об'єкт, асоцiйований з вказаним буфером; прикрiпити його до вже вiдкритого файлу, вказується дескриптор файла:

ifstream(int f, char *b, int len); ofstream(int f, char *b, int len); fstream (int f, char *b, int len);

1.7.2 ВIДКРИТТЯ ФАЙЛУ

Для вiдкриття файлу в С++ можна використовувати конструкто-

ри ifstream, ofstream, fstream:

#include<iostream.h>

#include<fstream.h>

#include<stdlib.h>

#include<ctype.h> int main(void)

346

{char fname[MAX];

cout<<“введіть ім’я вхідного файла”; cin >>fname;

//відкрити вхідний файл ifstream ifs(fname);

if (!ifs) {

cout <<"вiдкрити не можна"; return 0;}

cout<<“введіть ім’я вихідного файла”; cin >>fname;

ofstream ofs (fname); if(!ofs) {

cout <<"вiдкрити не можна"; return 0;}

char c;

while (ifs && ofs) {ifs.get(c); c=toupper(c); ofs.put(c);}

//завдання виконане

cout<<endl<<“Вихідний файл є копією вхідного у верхньому”

<<”регістрі”<<endl; return 0;}

Файл також може бути вiдкритий за допомогою метода open потоку fstream:

#include<iostream.h>

#include<fstream.h>

#include<stdlib.h> int main(void)

{//невідкритий об’єкт-потік fstream fin; cout<<“введіть iм'я файлу”;

char fname [MAX]; cin >>fname;

fin.open(fname, ios::in);

if (fin) {cout <<"файл вiдкритий успiшно"; fin.close();}

else cout<<"неможливо відкрити файл"<<endl; return 0;}

Режим доступу конструюється наступним чином: enum open.mode{

in=0x01,

out=0x02,

ate=0x04,

app=0x08,

347

trunc=0x10,

nocreate=0x20,

noreplase=0x40, binaru=0x80 };

in - для читання; out - для запису;

ate - вiдкриває та встановлює вказiвник на eof; app - для дописування в кiнець файлу;

trunc - перезаписує файл, якщо такий файл iснує (якщо нi - створює); nocrteate - вiдкриває файл, якщо вiн тiльки не iснує;

noreplase - вiдкриває файл, якщо вiн вже iснує; binary - двiйковий файл.,

Приклад (ілюстрація режимів доступу): int main(void)

{//створюється новий файл,якщо тільки він не існує ofstream ofs (fname,ios::out|ios::noreplase);

//перевірка стану потоку: if(!ofs)

{cout<<“помилка! Файл”<<fname<<“вже існує”<<endl; return 0;}

else{

//запис рядка в новий файл ofs<<“Привіт! Я - новий файл”; //файл закривається ofs.close();

// Визначити новий об’єкт fstream fs;

//відкрити файл та встановити на EOF ofs.open(fname,ios::out|ios::ate); fs<<"до якого дописано"; fs.close();

//Знову відкривається як вхідний fstream ifs (fname);

if(ifs)

{ cout<<“і старий файл сказав:”<<endl; //вислів старого файла

char line [MAX];

ifs.getline (line,sizeof(line)); cout <<line; }

else{cout<<“помилка при повторному відкрит-

ті”<<fname<<endl;}} return 0;}

Буферизацією потоку можна керувати за допомогою метода

348

setbuf. Ця функція асоцiює з потоком вказаний буфер: void setbuf (char*p,int len);

p - адреса,

len - довжина буфера.

В класах файлових потоків існує метод close, який а) опорожняє потік

б) Закриває закріплений за потоком файл Якщо при спробі закрити файл відбувається помилка, встановлюється

прапорець failbit стану потоку. Деструктр файлового об’єкта (чи його базового класу) повинен автоматично закривати файл.

1.8 НЕФОРМАТОВАНИЙ ВВІД-ВИВІД

Бінарні файли

Для вiдкриття файлу в бiнарному режимi необхiдно включити прапорець binary в параметрі open_mode, який передається в конструктор чи функцiї open. В наступному прикладі файл читається в текстовому та бінарному режимах:

#include<iostream.h>

#include<fstream.h>

#include<stdlib.h> int main(void)

{ cout<<"Введіть ім'я вхідного файла"; char fname[20];

cin>>fname;

ifstream ifbin(fname,ios::in|ios::binary); ifstream iftxt(fname,ios::in);

//одночасно вiдкриває файл

//у бiнарному i текстовому режимах if (!ifbin || !iftxt)

{cout <<"помилка"; return 0;}

int countbin=0;

do {if (ifbin.get()!=EOF) countbin++;}

while (ifbin);

cout <<"число символів, прочитаних в режимі binary"<<countbin;

int counttxt=0; do

{if (iftxt.get()!=EOF) counttxt++;} while(iftxt);

cout <<"число символів, прочитаних в режимі text"

349

<<counttxt; return 0; }

1.9 ДЕЯКІ ФУНКЦІЇ ВВОДУ-ВИВОДУ

Функція read()

Дозволяє дiставати з потоку вказану кiлькiсть символiв та записувати їх в буфер:

istream & istream::read(char*f,int len); istream & istream::read(singed char*f,int len);

istream & istream::read(unsinged char*f.int len); f - адреса,

len - довжина буфера. Функція write()

Помiщує в потiк вказане число символiв: istream & istream::write(const char*p,int len);

Приклад:

// Текстовий режим: int i=12345; long e=98765432;

double d=2.4 e 12;

const char bfname[]="io.bin"; const char tfname[]="io.txt"; int main(void){

ofstream ofs(fname); if (ofs)

{ofs <<i<<'\t' <<l<<'\t' <<d<<'\t'<<endl;

ofs.close();} ifstream ifs(tfname); if(ifs)

{ifs >>i>>l>>d; ifs.close();}

//Бiнарний режим:

ofs.open(bname,ios::out|ios::binary);

if(ofs)

{ofs.write ((char*)& i,sizeof(i)); ofs.write ((char*)& l,sizeof(l)); ofs.write ((char*)& d,sizeof(d)); ofs.close();} ifs.open(bname,ios::in|ios::binary) if(ifs)

350

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]