400 likes | 599 Views
Потоци. Потоците са обекти от потокови класове , които могат да се разглеждат като междинно звено между източниците на данни (те записват данни в потока) и приемниците на данни (те извличат данни от потока) I програмата.
E N D
Потоци • Потоците са обекти от потокови класове, които могат да се разглеждат като междинно звено между източниците на данни (те записват данни в потока) и приемниците на данни (те извличат данни от потока) I програмата. • Поток – логическо устройство, което въвежда или извежда информация (в/от програмата). програма програма програма поток поток Вх/изх. система Вх/изх. система устройство1 устройствоn
Потоци За форматиран вх/изход iostream.h Основни класове streambuf ios За управление на основни вх/изходни операции ios istream (вход) ostream(изход) iostream(вход/изход) ifstream istrstream ofstream ostrstream Връзка с RAM Връзка с файл Връзка с RAM Връзка с файл
Потоци • Операторът << “вмъква” информация в изходен поток, а >>“извлича” информация от входен поток. • Тези операции са предефинирани в класовете ostreamиistream за работа с базовите типове. ostream &operator <<Базов тип; istream &operator >>Базов тип; int a,b; cin >> a; //или cin >> a >> b; cin >> b; cout << a << b;
Потоци • Цел на предефиниранетона << и >>: class test { . . . . . . }; test a, b; cin >> a >> b; cout << a << b; Ако а и b са обекти от клас test
Потоци • Потокът може да се свърже към: • входно/изходно устройство (клавиатура, монитор,..) –> класове istreamили ostream ; • файл -> класове ifstreamили ofstream; • буфер от паметта -> класове istrstreamили ostrstream.
Потоци Предефиниране на потоковите операциите >> и << • За предефинирането на тези операции се използват приятелски функции поради факта, че първият параметър е поток, а не обект от съответния клас. • Връщаният резултат трябва да бъде псевдоним за да се осигури възможността за верижно използване на операциите. входен поток>>променлива_приемник изходен поток <<израз_източник Общ вид на използване
Потоци Предефиниране на потоковите операциите >> и << Общ виднадефиниции на функциите за предефиниране на >> и << istream &operator >> (istream &име_поток, тип_клас &обект) { //тяло return име_поток; } ostream &operator << (ostream &име_поток, тип_клас &обект) { //тяло return име_поток; }
Потоци Предефиниране на потоковите операциите >> и << • Примерилюстриращ функциите за предефиниране на операциите за извличане (>>)от поток и вмъкване (<<) в поток #include<iostream.h> 1/3 class object { int a; float b; public: object(int a1=0,float b1=0) {a=a1; b=b1; } friend istream &operator>>(istream &,object &); friend ostream &operator<<(ostream &,object &); };
Потоци Предефиниране на потоковите операциите >> и << • Примерилюстриращ функциите за предефиниране на операциите за извличане (>>)от поток и вмъкване (<<) в поток istream &operator>>(istream &x, object &o) 2/3 { cout<<"a="; x>>o.a; cout<<"b="; x>>o.b; return x; } ostream &operator<<(ostream &x, object &o) { x<<o.a<<" "<<o.b; return x; }
Потоци Предефиниране на потоковите операциите >> и << • Примерилюстриращ функциите за предефиниране на операциите за извличане (>>)от поток и вмъкване (<<) в поток void main() 3/3 { object x,y; cin>>x>>y; cout<<"Obektite sa:\n"; cout<<x<<"\n"<<y<<"\n"; } a=4 b=5 a=6 b=7 Obektite sa: 4 5 6 7
Потоци Дискови файлове • Библиотечният файл <fstream.h> се използва за вход/изход от файл и дефинира класовете: • ifstream(производен на istream) – за извличане; • ofstream (производен на ostream) – за вмъкване; • fstream (производен на istream и ostream) – за извличане и вмъкване
Потоци Дискови файлове Създаване,отваряне и затваряне на файл • Създаване на поток (файл) за вход, изход, вход/изход • Отваряне на файл чрез: • open – член-функция на трите потокови класа ifstream in; //входен поток ofstream out;//изходен поток fstream io;//входно/изходен поток Създаване на обекти void open(const char *filename,int mode, int access=filebuf::openprot);
Потоци Дискови файлове Създаване,отваряне и затваряне на файл • където modeе режим на отваряне на файла и може да бъде: • ios::app - за добавяне (вмъкване в края на файла) • ios::ate – позициониране в края на файла (може и четене) • ios::in – за извличане • ios::out – за вмъкване • ios::binary – двоичен файл • ios::trunc – изтриване на файла, ако съществува • ios::nocreate – отварянето пропада при несъществуващ файл • ios::noreplace – отварянето пропада при съществуващ файл
Потоци Дискови файлове Създаване,отваряне и затваряне на файл • access определя достъпа до файла и при filebuf::openprotсе отваря нормален файл (по подразбиране). Примери за създаване и отваряне на файл с open ofstream out; //създава файл за изход (запис) out.open(“test”,ios::out);//отваря файл за изход . . . ifstream in; //създава файл за вход (четене) in.open(“test”,ios::in);//отваря файл завход . . . fstream my;//създава файл за вход/изход my.open(“test”,ios::in | ios::out); //отваря файл за вход/изход
Потоци Дискови файлове Създаване,отваряне и затваряне на файл • Отваряне на файл чрез: • конструктор – едновременно се създава и отваря файл • Затваряне на файл ifstream my(“test”); //създава и отваря файл за вход (четене) void close(); my.close(); //затваря файл Пример
Потоци Дискови файлове Обмен на информация (четене/запис) • Обменът на информация може да се извършва чрез: • потоковите операции (за запис във файл: << и за четене от файл: >>); • член-функции на класовете istream и ostream. • Файлови операции могат да се извършват в два режима – текстов и двоичен.
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на текстови файлове -функции istream &getline(char *s,int size,char delim=’\n’); istream &get(char &); int gcount(); int eof(); Чете низ от входен поток до срещане на ограничител delim (последният не се прочита) с максимална дължина на низа size Чете един символ от входен поток и го въвежда в променливата – параметър Край на файл Връща извлечения брой символи при последното използване на getline().
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на текстови файлове #include<iostream.h> 1/3 #include<fstream.h> #include<stdlib.h> #include<iomanip.h> #include<ctype.h> #include<conio.h> const int NAME=15; void main() { char f_name[NAME]; cout<<"име на файл:"; cin>>setw(NAME-1)>>f_name; ofstream file_out(f_name,ios::out);//създава и отваря файл за запис if(!file_out) {cout<<"Файл не може да се създаде.\n"; exit(1); } Пример за създаване на текстов файл от символни низове, въвеждани от клавиатурата и четене на файла с извеждане на екран
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на текстови файлове char line[80]; 2/3 do { cout<<"\nвъведи символен низ ограничен със *:"; cin>>setw(80-1)>>line; file_out<<line;//запис на низа във файла cout<<"следващ символен низ:Y/N:";//чрез потокова операция }while(toupper(getch())=='Y'); file_out.close(); Създаване на текстов файл от символни низове, въвеждани от клавиатурата
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на текстови файлове ifstream file_in(f_name,ios::in);//отваря файл за четене 3/3 if(!file_in) { cout<<"Не може да се отвори файл за четене.\n"; exit(1); } while(!file_in.eof()) //четене на файла до край нафайл { file_in.getline(line,80,'*');//четене чрез член-функция }//или четене с cout<<'\n'<<line; file_in.close(); }//край на main Четене на файла с извеждане на екран
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на текстови файлове При изпълнение на програмата: име на файл:а въведи символен низ ограничен със *:ааа* следващ символен низ:Y/N: въведи символен низ ограничен със *:bbb* следващ символен низ:Y/N: aaa bbb
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на двоични файлове - функции четене и запис на един байт istream &get(char &ch); ostream &put(char ch); #include <iostream.h> #include <fstream.h> main(int argc, char *argv[ ]) { char ch; if( argc != 2) { cout << “стартирай с: progfilename”; return 1; } ifstream my(argv[1], ios :: in | ios :: binary); if( !my ) { cout << “файлът не може да се отвори!\n”; return 1; } while (my) { my.get(ch); cout << ch; } return 0; } Пример за четене и извеждане на съществуващ файл
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на двоични файлове - функции prog filename В Command Prompt Името на изпълнимия файл: prog.exe Името на съществуващия двоичен файл: filename.bin
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на двоични файлове - функции • Функцията вмъква (записва) зададен от size брой символи(байта) от буфера sв свързания файл (поток). Разликата от потоковата операция << е в управляващия символ за край на низ (тук той е символ от низа, а при потоковата операция е управляващия символ за край на низ). ostream &write(const char *s,int size);
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на двоични файлове - функции • Функцията извлича (чете) зададен от sizeброй символи от свързания файл в буфера s. • Достигането на край на файл преди прочитането на size байта спира read(). istream &read(char *s,int size);
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на двоични файлове #include<iostream.h> 1/4 #include<fstream.h> #include<stdlib.h> #include<ctype.h> #include<conio.h> class test { double x; int y; public: test() {} friend ostream &operator<<(ostream &,test &); friend istream &operator>>(istream &,test &); }; Пример: запис в двоичен файл на обекти с брой, определян по време на изпълнението, прочитане на файла и извеждане на съдържанието му
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на двоични файлове ostream &operator<<(ostream &outp,test &p) 2/4 { outp<<"\nobekt:"<<p.x<<","<<p.y<<"\n"; return outp; } istream &operator>>(istream &inp, test &p) { cout<<"\nx="; inp>>p.x; cout<<"y="; inp>>p.y; return inp; } Дефиниране на операция за вмъкване в поток Дефиниране на операция за извличане от поток
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на двоични файлове void main() 3/4 { test p; int i=1; ofstream file("test.bin",ios::out||ios::binary); if(!file) {cout<<"Файл не може да се създаде.\n"; exit(1); } do {cout<<'\n'<<i<<" запис във файла\n"; cout<<"въведи обект:"; cin>>p; file.write((char*)&p, sizeof(test));//запис във файла i++; cout<<"следващ?Y/N:"; }while(toupper(getch())=='Y'); file.close(); Запис на обекти във файла
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на двоични файлове ifstream file1("test.bin",ios::in||ios::binary); 4/4 if(!file1) { cout<<"Файл не може да се отвори.\n"; exit(1); } for(int j=1;j<i;j++) { file1.read((char*)&p, sizeof(test)); cout<<p; } file1.close(); } //край на main Четене на обекти от файла
Потоци Дискови файлове Обмен на информация (четене/запис) Четене/запис на двоични файлове При изпълнение на програмата: 1 запис във файла въведи обект: x=1 y=2 следващ?Y/N: 2 запис във файла въведи обект: x=3 y=4 следващ?Y/N: oбект 1,2 oбект 3,4
Потоци Дискови файлове Пряк достъп до файловете • Местоположението на вмъкваната или извличана информация при работа с файл се определя от указател на потока. Указателят се увеличава автоматично с едно при всяка операция. • Подържат се два указателя: 1) get – определя къде във файла ще бъде следващата операция четене; 2) put – определя къде ще бъде следващата операция запис. Функции за намиране на позицията на указателя long istream::telg(); //връща стойността на указател четене long ostream::telp();//връща стойността на указател запис
Потоци Дискови файлове Пряк достъп до файловете Функции за позициониране на указателя във файла istream &istream::seekg(long offset,where); ostream &ostream::seekp(long offset,where); задава относителното преместване на указателя спрямо позиция, определена от втория параметър ios::beg – от началото на потока ios::cur – от текущата позиция на потока ios::end – от края на потока
Потоци Дискови файлове Пряк достъп до файловете - Пример #include<iostream.h> 1/5 #include<fstream.h> #include<string.h> #include<stdlib.h> class phone {char name[80]; char code[4]; char num[5]; public: phone() {} phone(char *n,char *c,char *nm) {strcpy(name,n); strcpy(code,c); strcpy(num,nm); } friend ostream&operator<<(ostream &stream,phone &o); friend istream &operator>>(istream &stream,phone &o); }; Добавяне на нов елемент (обект) във файла на телефонен указател, извеждане на съдържанието на файла и търсене по име на запис във файла.
Потоци Дискови файлове Пряк достъп до файловете - Пример ostream&operator<<(ostream &stream,phone &o) 2/5 {stream<<o.name<<" "; stream<<o.code<<" "; stream<<o.num<<"\n"; return stream; } istream &operator>>(istream &stream,phone &o) { cout<<“въведи елемент\n” cout<<"име:"; stream>>o.name; cout<<"код:"; stream>>o.code; cout<<"номер:"; stream>>o.num; return stream; } Дефиниране на операции за вмъкване и извличане от поток
Потоци Дискови файлове Пряк достъп до файловете - Пример void main() 3/5 { phone a; char c; int flag=0; fstream p("phone",ios::in|ios::out|ios::app); if(!p) {exit(1);} for(;;) { do { cout<<"1.въвеждане\n"; cout<<"2.извеждане\n"; cout<<"3.търсене\n"; cout<<"4.край\n"; cout<<"\nвъведи избор: "; cin>>c; }while(c<'1'||c>'4'); Отваря файл за четене, запис, добавяне
Потоци Дискови файлове Пряк достъп до файловете - Пример switch(c) { 4/5 case '1':cin>>a; cout<<"Vavedeno e\n"; cout<<a; p<<a; break; case '2':char ch; p.seekg(0,ios::beg); //позициониране while(!p.eof()) { p.get(ch); cout<<ch; } p.clear();//reset eof cout<<endl; break; Операции за запис на нов елемент и четене на файла
Потоци Дискови файлове Пряк достъп до файловете - Пример case '3':char name_d[80],buf[80]; 5/5 cout<<"въведи име за търсене:"; cin>>name_d; p.seekg(0,ios::beg);//позициониране while(!p.eof()) {p.getline(buf,80,'\n '); if(!strncmp(name_d,buf,strlen(name_d))) {flag=1; cout<<"намерен елемент\n";break; } } if(!flag) cout<<"няма елемент\n"; break; case '4':p.close();exit(1); } //край на switch } //край на цикъл for } //край на main Операции за търсене по име на елемент във файла и край
Потоци Дискови файлове Пряк достъп до файловете - Пример Резултат при създаване на файла Резултат при търсене във файла 1.въвеждане 2.извеждане 3.търсене 4.край въведи избор:1 име:Ана код:1000 номер:66 въведено е: Ана 1000 66 1.въвеждане 2.извеждане 3.търсене 4.край въведи избор:2 Ана 1000 66 1.въвеждане 2.извеждане 3.търсене 4.край въведи избор:3 въведи име за търсене:Ана намерен елемент въведи име за търсене:Иван няма елемент
Потоци Namespace – пространство на имената • Механизъм за изразяване на логическо групиране на декларации на функции namespace A { double a(); double b(); double c(); using namespace B; //достъп до всички имена в В } double A :: a( ) { . . . } //дефиниция недостъпна за потребителя . . . namespace A_interface //интерфейс за потребител { using A :: a; }
Потоци Изключения • Разделя се съобщение за грешка от управление на грешка. • Ако програмата проверява за изключение, то тя ги прихваща (catch). • Кодът, който открива грешката (библиотека от грешки) стартира (throw) обект. • Този обект е параметър на catch. try { f(); //код изпълняван, ако f() работи коректно throw new . . . //създава се обект } catch(грешка_1) { //управление на грешка_1 } catch(грешка_2) { //управление на грешка_2 } . . .