Fungovanie I/O súboru v C++ je takmer rovnaké ako bežné I/O (ale s niekoľkými nuansami).

Súbor I/O tried

Existuje tri hlavné triedy I/O súborov v C++:

mimo prúdu(je dieťaťom triedy);

fstream(je dieťaťom triedy iostream).

Pomocou týchto tried môžete vykonávať jednosmerný vstup súboru, jednosmerný výstup súboru a obojsmerný vstup/výstup súboru. Ak ich chcete použiť, stačí pripojiť fstream.

Na rozdiel od streamov cout, cin, cerr a clog, ktoré sú okamžite použiteľné, toky súborov musí explicitne nastaviť programátor. To znamená, že ak chcete otvoriť súbor na čítanie a/alebo zápis, musíte vytvoriť objekt príslušnej I/O triedy súboru, pričom ako parameter uvediete názov súboru. Potom pomocou operátorov vkladania (<<) или извлечения (>>), môžete zapisovať údaje do súboru alebo čítať obsah súboru. Potom konečná - musíte súbor zavrieť: výslovne zavolať close() metóda alebo jednoducho nechajte premennú I/O súboru mimo rozsahu (trieda I/O súboru za nás tento súbor automaticky zatvorí).

Výstup súboru

Trieda ofstream sa používa na zápis do súboru. Napríklad:

#include #include #include // použiť exit() int main() (pomocou menného priestoru std; // ofstream sa používa na zápis údajov do súboru // Vytvorenie súboru SomeText.txt ofstream outf("SomeText.txt"); // Ak môžeme 't otvorte tento súbor na zápis údajov do if (!outf) ( // Potom vytlačte chybové hlásenie a spustite exit() cerr<< "Uh oh, SomeText.txt could not be opened for writing!" << endl; exit(1); } // Записываем в файл следующие две строчки outf << "See line #1!" << endl; outf << "See line #2!" << endl; return 0; // Когда outf выйдет из области видимости, то деструктор класса ofstream автоматически закроет наш файл }

#include

#include

#include // na použitie exit()

int main()

pomocou menného priestoru std ;

// ofstream sa používa na zapisovanie údajov do súboru

// Vytvorenie súboru SomeText.txt

ofstream outf("SomeText.txt" ) ;

// Ak nemôžeme tento súbor otvoriť, aby sme doň zapísali údaje

ak(!outf)

// Potom vytlačte chybové hlásenie a spustite exit()

cerr<< << endl ;

exit(1) ;

// Do súboru zapíšeme nasledujúce dva riadky

outf<< "See line #1!" << endl ;

outf<< "See line #2!" << endl ;

návrat 0;

// Keď outf prekročí rozsah, deštruktor triedy ofstream automaticky zatvorí náš súbor

Ak sa pozriete do adresára projektu ( RMB na karte s názvom vášho súboru .cpp vo Visual Studiu > "Otvoriť priečinok obsahujúci"), uvidíte súbor s názvom SomeText.txt, ktorý obsahuje nasledujúce riadky:

Pozri riadok #1!
Pozri riadok #2!

Upozorňujeme, že môžeme použiť aj put() metóda na zapísanie jedného znaku do súboru.

Vstup súboru

#include #include #include #include // použiť exit() int main() (pomocou menného priestoru std; // ifstream sa používa na čítanie obsahu súboru // Skúste prečítať obsah súboru SomeText.txt ifstream inf("SomeText.txt") ; // Ak nemôžeme tento súbor otvoriť a prečítať si jeho obsah if (!inf) ( cerr<< "Uh oh, SomeText.txt could not be opened for reading!" << endl; exit(1); } // Пока есть данные, которые мы можем прочитать while (inf) { // То перемещаем эти данные в строку, которую затем выводим на экран string strInput; inf >> strInput; cout<< strInput << endl; } return 0; }

#include

#include

#include

#include // na použitie exit()

int main()

pomocou menného priestoru std ;

// ifstream sa používa na čítanie obsahu súboru

// Ak nemôžeme tento súbor otvoriť a prečítať si jeho obsah

if(!inf)

// Potom vytlačte nasledujúce chybové hlásenie a spustite exit()

cerr<< << endl ;

exit(1) ;

// Pokiaľ existujú údaje, ktoré môžeme čítať

while(inf)

// Potom tieto údaje presunieme do reťazca, ktorý následne zobrazíme na obrazovke

string strInput ;

inf >> strInput ;

cout<< strInput << endl ;

návrat 0;

// Keď inf prekročí rozsah, deštruktor triedy ifstream automaticky zatvorí náš súbor

Pozri
riadok
#1!
Pozri
riadok
#2!

Hmm, nie je to celkom to, čo sme chceli. Ako už vieme z predchádzajúcich lekcií, operátor extrakcie pracuje s „formátovanými dátami“, t.j. ignoruje všetky medzery, tabulátory a nové riadky. Na čítanie celého obsahu tak, ako je, bez jeho rozdelenia na časti (ako v príklade vyššie), musíme použiť metóda getline().:

#include #include #include #include // použiť exit() int main() (pomocou menného priestoru std; // ifstream sa používa na čítanie obsahu súborov // Pokúsime sa prečítať obsah súboru SomeText.txt ifstream inf("SomeText.txt") ; // Ak nemôžeme otvoriť súbor a prečítať si jeho obsah if (!inf) ( // Potom vytlačte nasledujúce chybové hlásenie a ukončite() cerr<< "Uh oh, SomeText.txt could not be opened for reading!" << endl; exit(1); } // Пока есть, что читать while (inf) { // То перемещаем то, что можем прочитать, в строку, а затем выводим эту строку на экран string strInput; getline(inf, strInput); cout << strInput << endl; } return 0; // Когда inf выйдет из области видимости, то деструктор класса ifstream автоматически закроет наш файл }

#include

#include

#include

#include // na použitie exit()

int main()

pomocou menného priestoru std ;

// ifstream sa používa na čítanie obsahu súborov

ifstream inf("NiejakyText.txt" ) ;

// Ak nemôžeme otvoriť súbor, aby sme si prečítali jeho obsah

if(!inf)

// Potom vytlačte nasledujúce chybové hlásenie a spustite exit()

cerr<< "Och, SomeText.txt sa nepodarilo otvoriť na čítanie!"<< endl ;

exit(1) ;

while(inf)

string strInput ;

getline (inf , strInput ) ;

cout<< strInput << endl ;

návrat 0;

// Keď inf prekročí rozsah, deštruktor triedy ifstream automaticky zatvorí náš súbor

Výsledkom spustenia vyššie uvedeného programu je:

výstup s vyrovnávacou pamäťou

Výstup v C++ je možné uložiť do vyrovnávacej pamäte. To znamená, že všetko, čo je na výstupe do prúdového súboru súborov, nemôže byť okamžite zapísané na disk (do konkrétneho súboru). Deje sa tak predovšetkým z výkonnostných dôvodov. Keď sa dáta vyrovnávacej pamäte zapisujú na disk, volá sa to čistenie vyrovnávacej pamäte. Jedným zo spôsobov, ako vyčistiť vyrovnávaciu pamäť, je zatvoriť súbor. V tomto prípade sa celý obsah vyrovnávacej pamäte presunie na disk a potom sa súbor zatvorí.

Výstupná vyrovnávacia pamäť zvyčajne nie je problémom, ale za určitých okolností môže spôsobiť problémy neopatrným nováčikom. Napríklad, keď sú dáta uložené vo vyrovnávacej pamäti a program predčasne ukončí ich vykonávanie (buď v dôsledku zlyhania alebo volaním ). V takýchto prípadoch sa deštruktory tried I/O súborov nevykonajú, súbory sa nikdy nezatvoria, vyrovnávacie pamäte sa nevyprázdnia a naše údaje sa navždy stratia. Preto je dobré pred volaním exit() explicitne zatvoriť všetky otvorené súbory.

Vyrovnávaciu pamäť môžete vymazať aj manuálne pomocou ostream::flush() metóda alebo odoslaním std::flush do výstupného prúdu. Ktorákoľvek z týchto metód môže byť užitočná na zabezpečenie okamžitého zápisu obsahu vyrovnávacej pamäte na disk v prípade zlyhania programu.

Zaujímavá nuansa: Pretože std::endl; tiež vymaže výstupný tok, jeho nadmerné používanie (vedúce k zbytočnému vyprázdneniu vyrovnávacej pamäte) môže ovplyvniť výkon programu (pretože vyprázdnenie vyrovnávacej pamäte môže byť v niektorých prípadoch drahé). Z tohto dôvodu programátori, ktorí dbajú na výkon, často používajú \n namiesto std::endl na vloženie znaku nového riadku do výstupného toku, aby sa vyhli zbytočnému preplachovaniu vyrovnávacej pamäte.

Režimy otvárania súborov

Čo sa stane, ak sa pokúsime zapísať údaje do už existujúceho súboru? Opätovné spustenie programu vyššie (úplne prvý) ukazuje, že pôvodný súbor je pri opätovnom spustení programu úplne prepísaný. Čo ak však potrebujeme pridať údaje na koniec súboru? Ukázalo sa, že tok súboru má voliteľný druhý parameter, ktorý vám umožňuje povedať programátorovi, ako má súbor otvoriť. Ako tento parameter môžete prejsť nasledujúce vlajky(ktoré sú v triede ios):

aplikácie- otvorí súbor v režime pripojenia;

jedol- prejde na koniec súboru pred čítaním/zápisom;

binárne- otvorí súbor v binárnom režime (namiesto textového režimu);

v- otvorí súbor v režime čítania (predvolené pre ifstream);

von- otvorí súbor v režime zápisu (predvolené pre ofstream);

trunc- vymaže súbor, ak už existuje.

Môžete zadať viacero príznakov naraz pomocou .

ifstream štandardne funguje v režime ios::in;

ofstream štandardne funguje v režime ios::out;

fstream štandardne beží v režime ios::in OR ios::out, čo znamená, že môžete čítať obsah súboru alebo zapisovať údaje do súboru.

Teraz napíšme program, ktorý pridá dva riadky do predtým vytvoreného súboru SomeText.txt:

#include #include // na použitie exit() #include int main() ( s použitím menného priestoru std; // Odovzdaním príznaku ios:app oznámime fstreamu, že sa chystáme pripojiť naše údaje k už existujúcim údajom súboru, // súbor neprepíšeme. Nie je potrebné odovzdať príznak ios::out , // pretože ofstream je predvolene nastavený na ios::out ofstream outf("SomeText.txt", ios::app); // Ak nemôžeme otvoriť súbor na zapisovanie údajov, ak (!outf) ( // Potom výstup nasledujúce chybové hlásenie a exit() cerr<< "Uh oh, SomeText.txt could not be opened for writing!" << endl; exit(1); } outf << "See line #3!" << endl; outf << "See line #4!" << endl; return 0; // Когда outf выйдет из области видимости, то деструктор класса ofstream автоматически закроет наш файл }

#include

#include // na použitie exit()

#include

int main()

pomocou menného priestoru std ;

// Odovzdaním príznaku ios:app oznámime fstreamu, že svoje údaje pridáme k už existujúcim údajom súboru,

// súbor neprepíšeme. Nepotrebujeme odovzdať príznak ios::out,

// pretože ofstream je štandardne nastavený na režim ios::out

ofstream outf("SomeText.txt" , ios::app ) ;

// Ak nemôžeme otvoriť súbor na zápis údajov

ak(!outf)

// Potom vytlačte nasledujúce chybové hlásenie a spustite exit()

cerr<< "Och, SomeText.txt sa nepodarilo otvoriť na zápis!"<< endl ;

exit(1) ;

Mechanizmus I/O vyvinutý spoločnosťou , nezodpovedá dnes všeobecne akceptovanému štýlu objektovo orientovaného programovania, navyše aktívne využíva operácie ukazovateľov, ktoré sú v moderných prostrediach vykonávania bezpečného kódu považované za potenciálne nebezpečné. Alternatívou pre vývoj aplikácií je štandardný mechanizmus I/O tried poskytovaný štandardom jazyka C++.

Otváranie súborov

Najčastejšie používané triedy sú ifstream na čítanie, ofstream na zápis a fstream na úpravu súborov.

Všetky vlákna I/O triedy sú nepriamo odvodené od spoločného predka ios, pričom plne zdedia jeho funkčnosť. Napríklad enumerovaný dátový člen open_mode špecifikuje režim otvárania súboru, ktorý je definovaný takto:

Enum open_mode ( app, binary, in, out, trunc, ate );

Nižšie sú uvedené možné hodnoty vlajok a ich účel.

Ak chcete napríklad otvoriť súbor s názvom test.txt na čítanie binárnych údajov, napíšte:

súbor ifstream; file.open("test.txt", ios::in | ios::binary);

Logický operátor OR (|) vám umožňuje zostaviť režim s ľubovoľnou kombináciou príznakov. Aby ste pri otváraní súboru zápisom omylom neprepísali existujúci súbor s rovnakým názvom, musíte použiť nasledujúci formulár:

offstream súbor; file.open("test.txt", ios::out | ios::app);

Predpokladá sa, že príslušný hlavičkový súbor je pripojený k projektu:

#include

Ak chcete skontrolovať, či bol súbor úspešne otvorený, môžete použiť konštrukciu

If (!file) ( // Spracovanie chyby pri otvorení súboru )

Operátori inklúzie a ťažby

Prepísané v triedach spracovania súborov zahŕňať operátora (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

súbor<< "Это строка текста";

Textový reťazec môžete napísať aj po častiach:

súbor<< "Это " << "строка " << "текста";

Príkaz endl ukončí vstup riadku návratom vozíka:

súbor<< "Это строка текста" << endl;

Pomocou operátora include je ľahké zapísať hodnoty premenných alebo prvkov poľa do súboru:

Ofstream súbor("Temp.txt"); char buff = "Textové pole obsahuje premenné"; int vx = 100; float pi = 3,14159; súbor<< buff << endl << vx << endl << pi << endl;

V dôsledku spustenia kódu sa vygenerujú tri riadky textového súboru Temp.txt:

Textové pole obsahuje premenné 100 3,14159

Všimnite si, že číselné hodnoty sa do súboru zapisujú ako textové reťazce, nie binárne hodnoty.

operátor extraktu(>>) robí pravý opak. Zdá sa, že ak chcete extrahovať znaky zo súboru Temp.txt napísaného skôr, musíte napísať kód, ako je tento:

ifstream súbor("Temp.txt"); char buff; intvx; floatpi; súbor >> buff >> vx >> pi;

Operátor extrakcie sa však zastaví pri prvom oddeľovači (medzera, tabulátor alebo nový riadok), na ktorý narazí. Pri analýze vety „Textové pole obsahuje premenné“ sa teda do poľa buff zapíše iba slovo „Text“, medzera sa ignoruje a slovo „pole“ sa stane hodnotou celočíselnej premennej vx a kódu exekúcia sa „zničí“ s nevyhnutným porušením štruktúry údajov. Ďalej si pri diskusii o triede ifstream ukážeme, ako správne zorganizovať čítanie súboru z predchádzajúceho príkladu.

trieda ifstream: čítanie súborov

Ako už názov napovedá, trieda ifstream je navrhnutá na vstup dátového toku súboru. Hlavné metódy triedy sú uvedené nižšie. Väčšina z nich je zdedená z triedy istream a preťažená nadradenou funkcionalitou. Napríklad funkcia get v závislosti od parametra volania dokáže prečítať nielen jeden znak, ale aj blok znakov.

Teraz je jasné, ako musíte upraviť predchádzajúci príklad, aby použitie operátora extrakcie údajov poskytlo očakávaný výsledok:

ifstream súbor("Temp.txt"); char buff; intvx; floatpi; file.getline(buff, sizeof(buff)); súbor >> vx >> pi:

Metóda getline prečíta prvý riadok súboru až do konca a operátor >> priradí hodnoty premenným.

Nasledujúci príklad ukazuje pridávanie údajov do textového súboru a následné čítanie celého súboru. Cyklus while (1) sa používa namiesto while(!file2.eof()) z dôvodov uvedených v .

#include #include pomocou menného priestoru std; int main() ( súbor ofstream; file.open("test.txt",ios::out|ios::app); if (!súbor) ( cout<< "File error - can"t open to write data!"; cin.sync(); cin.get(); return 1; } for (int i=0; i<10; i++) file << i << endl; file.close(); ifstream file2; file2.open("test.txt", ios::in); if (!file2) { cout << "File error - can"t open to read data!"; cin.sync(); cin.get(); return 2; } int a,k=0; while (1) { file2 >>a; if (file2.eof()) break; cout<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

Nasledujúci príklad prechádza čítaním riadkov zo súboru test.txt a ich zobrazením na konzole.

#include #include pomocou menného priestoru std; int main() ( súbor ifstream; // vytvorenie súboru objektu streamu file.open("test.txt"); // otvorenie súboru na čítanie if (!súbor) návrat 1; // návrat pri chybe pri otváraní char str; / / static line buffer // Čítanie a zobrazovanie riadkov v slučke až do eof while (!file.getline(str, sizeof(str)).eof()) cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

Tento kód pod OS Windows závisí aj od prítomnosti znaku nového riadku v poslednom riadku súboru, spoľahlivejšie by bolo:

While (1) ( if (file.eof()) break; file.getline(str, sizeof(str)); cout<< str << endl; }

Explicitné volania metód otvorenia a zatvorenia sú voliteľné. Volanie konštruktora s argumentom vám skutočne umožňuje otvoriť súbor okamžite, v momente, keď je vytvorený objekt streamu súboru:

ifstream súbor("test.txt");

Namiesto metódy close môžete použiť operátor delete, ktorý automaticky zavolá deštruktor súborového objektu a zatvorí súbor. Kód cyklu while poskytuje správnu kontrolu konca súboru.

ofstream trieda: písanie súborov

Trieda ofstream je navrhnutá na výstup údajov zo súborového toku. Hlavné metódy tejto triedy sú uvedené nižšie.

Operátor include opísaný vyššie je vhodný na organizáciu zápisu do textového súboru:

Ofstream súbor("temp.txt"); if (!file) return; pre (int i=1; i<=3; i++) file << "Строка " << i << endl; file.close();

Binárne súbory

V zásade sa binárne dáta obsluhujú ako textové dáta. Rozdiel je v tom, že ak sú binárne dáta zapísané v určitej logickej štruktúre, potom sa musia zo súboru načítať do premennej rovnakého typu štruktúry.

Prvý parameter metód zápisu a čítania (adresa bloku zápisu/čítania) musí byť typu znakového ukazovateľa char * , preto je potrebné explicitne previesť typ adresy štruktúry void *. Druhý parameter určuje, že binárne bloky súboru majú konštantnú veľkosť bajtov bez ohľadu na skutočnú dĺžku záznamu. V nasledujúcom dodatku je uvedený príklad vytvárania a zobrazovania údajov v jednoduchom poznámkovom bloku. Záznamy súboru sa potom načítajú postupne a zobrazia sa na konzole.

#include #include #include pomocou menného priestoru std; struct Notes ( // dátová štruktúra zápisníka char Name; // celé meno char Phone; // phone int Age; // age ); int main() ( setlocale(LC_ALL, "Russian"); Notes Note1= ("Grozny Ioann Vasilyevich", "nenainštalované", 60 ); Notes Note2= ("Godunov Boris Fedorovich", "095-111-2233 ", 30 ); Notes Note3= ( "Peter Romanov ", "812-333-2211 ", 20 ); ofstream ofile("Notebook.dat", ios::binary); ofile.write((char*)&Note1, sizeof ( Notes)); // 1. blok súboru.write((znak*)&Poznámka2, veľkosť(Poznámky)); // 2. blok súboru.write((znak*)&Poznámka3, veľkosť(Poznámky)); / / 3. blok súboru. close(); // zatvorí zapísaný súbor ifstream ifile("Notebook.dat", ios::binary); Notes Note; // štruktúrovaná premenná char str; // vyrovnávacia pamäť statických reťazcov // Čítanie a zobrazovanie riadkov v slučke, kým eof while (!file.read((char*)&Poznámka, veľkosť(Poznámky)).eof()) ( sprintf(str, "%s\tTelo: %s\tVek: %d" , Názov poznámky, Poznámka. Telefón, Poznámka.Vek); cout<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

V dôsledku vykonania tohto kódu sa vytvorí binárny súbor Notebook.dat z troch blokov po 80 bajtov (za predpokladu, že znaky sú jednobajtové). Prirodzene, môžete použiť aj iné metódy streamovania a vykonávať akúkoľvek operáciu na poliach konkrétnej dátovej štruktúry.

trieda fstream: náhodný prístup k súborom

Predpokladajme, že náš zápisník má nazhromaždených 100 záznamov a my chceme napočítať 50. Samozrejme, môžete usporiadať slučku a prečítať všetky záznamy od prvého po daný. Je zrejmé, že cielenejším riešením je nastaviť ukazovateľ polohy súboru POS priamo na záznam 50 a prečítať ho:

ifstream ifile("Notebook.dat", ios::binary); int pos = 49 * sizeof(Notes); ifile find(pos); // hľadanie 50. položky Poznámky Poznámka; //Poznámky - štruktúra "záznam" popísaná vyššie ifile.read((char*)&Note, sizeof(Notes));

Takéto operácie vyhľadávania sú účinné, ak súbor pozostáva zo záznamov známej a konštantnej veľkosti. Ak chcete nahradiť obsah ľubovoľnej položky, musíte otvoriť výstupný tok v režime úprav:

Ofstream ofile("Notebook.dat", ios::binary | ios::ate); int pos = 49 * sizeof(Notes); ofile seekp(pos); // hľadanie 50. noty Notes Note50 = ("Jeľcin Boris Nikolajevič", "095-222-3322", 64); ofile.write((znak*)&Poznámka, veľkosť(Poznámky)); // výmena

Ak nešpecifikujete príznak ios::ate (alebo ios::app), potom pri otvorení binárneho súboru Notebook.dat bude jeho predchádzajúci obsah vymazaný!

Nakoniec je možné otvoriť súbor súčasne na čítanie/zápis pomocou metód zdedených triedou streamovania fstream od svojich predchodcov. Keďže trieda fstream je odvodená od istream a ostream (rodičov ifstream a ofstream), všetky vyššie uvedené metódy sú dostupné pre aplikáciu.

Nasledujúci príklad zamieňa prvú a tretiu položku v súbore Notebook.dat.

#include #include #include pomocou menného priestoru std; struct Notes ( char Name; char Phone; int Age; ); int main() ( setlocale(LC_ALL, "Russian"); Notes Note1, Note3; // Otvorenie súboru na súčasné čítanie/zápis fstream file("Notebook.dat", ios::binary | ios::in | ios:: out); file.seekg(2 * sizeof(Notes)); // nájsť a prečítať Note3 file.read((char*)&Note3, sizeof(Notes)); file.seekg(0); // nájsť a prečítať Note1 file.read((char*)&Note1, sizeof(Notes)); file.seekg(0); // Poznámka1<== Note3 file.write((char*)&Note3, sizeof(Notes)); file.seekg(2 * sizeof(Notes)); // Note3 <== Note1 file.write((char*)&Note1, sizeof(Notes)); char str; // Считывать и отображать записи в цикле, пока не eof file.seekg(0); // вернуться к началу файла while (!file.read((char*)&Note1, sizeof(Notes)).eof()) { sprintf(str, "%s\tТел: %s\tВозраст: %d", Note1.Name, Note1.Phone, Note1.Age); cout << str << endl; } file.close(); cin.sync(); cin.get(); return 0; }

Príznaky ios::in a ios::out musia byť špecifikované v konštruktore súborového objektu, aby sa umožnili súbežné operácie čítania a zápisu. V dôsledku vykonania tohto kódu dôjde k zámene prvého a tretieho záznamu binárneho súboru Notebook.dat.

K téme sú aj ďalšie príklady.

Väčšina počítačových programov pracuje so súbormi, a preto je potrebné súbory vytvárať, mazať, zapisovať, čítať, otvárať. Čo je súbor? Súbor je pomenovaná kolekcia bajtov, ktorá môže byť uložená na nejakom úložnom zariadení. Teraz je jasné, že súbor je nejaká sekvencia bajtov, ktorá má svoj vlastný jedinečný názov, ako napríklad súbor .txt. Súbory s rovnakým názvom nemôžu byť v rovnakom adresári. Názov súboru sa chápe nielen ako jeho názov, ale aj ako prípona, napríklad: súbor.txt a súbor.dat rôzne súbory, hoci majú rovnaký názov. Existuje niečo ako úplný názov súborov - je to úplná adresa do adresára súboru s názvom súboru, napríklad: D:\docs\file.txt . Je dôležité pochopiť tieto základné pojmy, inak bude ťažké pracovať so súbormi.

Ak chcete pracovať so súbormi, musíte zahrnúť súbor hlavičky . AT definovaných niekoľko tried a hlavičkových súborov vstup do súboru a výstup súboru.

Súborový I/O je podobný štandardnému I/O, jediný rozdiel je v tom, že I/O sa nerobí na obrazovke, ale do súboru. Ak sa vstup/výstup na štandardné zariadenia vykonáva pomocou objektov cin a cout, potom na organizáciu I/O súboru stačí vytvoriť vlastné objekty, ktoré sa dajú použiť podobne ako operátory cin a cout.

Napríklad musíte vytvoriť textový súbor a napísať doň riadok Práca so súbormi v C++. Ak to chcete urobiť, musíte vykonať nasledujúce kroky:

  1. vytvoriť objekt triedy prúdu ;
  2. priradiť objekt triedy k súboru, do ktorého sa má zapisovať;
  3. napísať riadok do súboru;
  4. zatvorte súbor.

Prečo je potrebné vytvoriť objekt triedy ofstream a nie triedy ifstream? Pretože potrebujete zapisovať do súboru a ak by ste potrebovali čítať údaje zo súboru, potom by sa vytvoril objekt triedy ifstream.

// vytvorte objekt na zápis do súboru ofstream /*názov objektu*/; // objekt triedy prúdu

Nazvime objekt - fout , Tu je to, čo sa stane:

Ofstream fout;

Prečo potrebujeme predmet? Objekt musí byť schopný zapisovať do súboru. Objekt už bol vytvorený, ale nie je priradený k súboru, do ktorého sa má reťazec zapísať.

fout.open("cppstudio.txt"); // priradiť objekt k súboru

Operáciou bodka získame prístup k metóde triedy open(), v ktorej zátvorke uvádzame názov súboru. Zadaný súbor sa vytvorí v aktuálnom adresári s programom. Ak existuje súbor s rovnakým názvom, existujúci súbor bude nahradený novým. Súbor je teda otvorený, zostáva doň napísať požadovaný riadok. Robí sa to takto:

Fout<< "Работа с файлами в С++"; // запись строки в файл

Pomocou operácie cast to stream v spojení s objektom fout sa reťazec File Handling v C++ zapíše do súboru. Keďže už nie je potrebné meniť obsah súboru, musí byť uzavretý, to znamená, že objekt by mal byť oddelený od súboru.

fout.close(); // zatvorte súbor

V dôsledku toho bol vytvorený súbor s riadkom Práca so súbormi v C++.

Kroky 1 a 2 je možné kombinovať, to znamená vytvoriť objekt v jednom riadku a priradiť ho k súboru. Robí sa to takto:

Ofstream fout("cppstudio.txt"); // vytvoríme objekt triedy ofstream a priradíme ho k súboru cppstudio.txt

Skombinujme celý kód a získame nasledujúci program.

// file.cpp: definuje vstupný bod pre aplikáciu konzoly. #include "stdafx.h" #include pomocou menného priestoru std; int main(int argc, char* argv) ( ofstream fout("cppstudio.txt"); // vytvorte objekt triedy ofstream na zápis a priraďte ho k súboru cppstudio.txt fout<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

Zostáva skontrolovať správnu činnosť programu, a preto súbor otvoríme cppstudio.txt a pozrite sa na jeho obsah, malo by to byť - Práca so súbormi v C++.

  1. vytvorte objekt triedy ifstream a priraďte ho k súboru, z ktorého sa má čítať;
  2. čítať súbor;
  3. zatvorte súbor.
// file_read.cpp: definuje vstupný bod pre aplikáciu konzoly. #include "stdafx.h" #include #include pomocou menného priestoru std; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // správne zobrazenie char buff v azbuke; // prechodná vyrovnávacia pamäť pre text načítaný zo súboru ifstream fin("cppstudio.txt "); // otvorený súbor na čítanie fin >><< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку system("pause"); return 0; }

Program ukazuje dva spôsoby čítania zo súboru, prvým je použitie operácie prenosu do prúdu, druhým je použitie funkcie getline() . V prvom prípade sa číta iba prvé slovo a v druhom prípade sa číta reťazec 50 znakov. Ale keďže v súbore zostáva menej ako 50 znakov, znaky sa čítajú až po posledný vrátane. Všimnite si, že čítanie druhýkrát (riadok 17) pokračoval po prvom slove a nie od začiatku, pretože prvé slovo bolo prečítanériadok 14. Výsledok programu je znázornený na obrázku 1.

Práca so súbormi v C++ Pokračujte stlačením ľubovoľného klávesu. . .

Obrázok 1 - Práca so súbormi v C++

Program fungoval správne, ale nie vždy to tak je, aj keď je s kódom všetko v poriadku. Programu bol odovzdaný napríklad názov neexistujúceho súboru alebo sa v názve vyskytla chyba. Čo potom? V tomto prípade sa nestane vôbec nič. Súbor sa nenájde, čo znamená, že ho nie je možné prečítať. Preto bude kompilátor ignorovať riadky, kde sa so súborom manipuluje. V dôsledku toho sa program ukončí správne, ale na obrazovke sa nič nezobrazí. Zdalo by sa, že je to úplne normálna reakcia na takúto situáciu. Jednoduchý používateľ však nepochopí, o čo ide a prečo sa na obrazovke neobjavil riadok zo súboru. Takže, aby bolo všetko veľmi jasné, C++ poskytuje takúto funkciu - is_open() , ktorá vracia celočíselné hodnoty: 1 - ak bol súbor úspešne otvorený, 0 - ak súbor nebol otvorený. Dokončite program otvorením súboru tak, že ak sa súbor neotvorí, zobrazí sa zodpovedajúca správa.

// file_read.cpp: definuje vstupný bod pre aplikáciu konzoly. #include "stdafx.h" #include #include pomocou menného priestoru std; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // správne zobrazenie cyrilského znakového buffu; // prechodná vyrovnávacia pamäť textu načítaného zo súboru ifstream fin("cppstudio.doc"); / / ( ZADANÝ NESPRÁVNY NÁZOV SÚBORU) if (!fin.is_open()) // ak súbor nie je otvorený cout<< "Файл не может быть открыт!\n"; // сообщить об этом else { fin >> buff; // prečítanie prvého slova zo súboru cout<< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку } system("pause"); return 0; }

Výsledok programu je znázornený na obrázku 2.

Súbor sa nedá otvoriť! Pre pokračovanie stlačte ľubovolnú klávesu. . .

Obrázok 2 - Práca so súbormi v C++

Ako môžete vidieť na obrázku 2, program hlásil, že súbor nie je možné otvoriť. Preto, ak program pracuje so súbormi, odporúča sa použiť túto funkciu is_open() , aj keď ste si istí, že súbor existuje.

Režimy otvárania súborov

Režimy otvárania súborov určujú, ako sa súbory používajú. Na nastavenie režimu poskytuje trieda ios_base konštanty, ktoré určujú režim otvárania súboru (pozri tabuľku 1).

Režimy otvárania súborov je možné nastaviť priamo pri vytváraní objektu alebo pri volaní funkcie open(). .

Ofstream fout("cppstudio.txt", ios_base::app); // otvorenie súboru na pridanie informácií na koniec súboru fout. open("cppstudio.txt", ios_base::app); // otvorenie súboru na pridanie informácií na koniec súboru

Režimy otvárania súboru je možné kombinovať pomocou bitovej booleovskej operácie alebo| , napríklad: ios_base::out | ios_base::trunc - otvorenie súboru na zápis po jeho vymazaní.

Objekty triedy ofstream , keď sú spojené so súbormi, štandardne obsahujú režimy otvárania súborov ios_base::out | ios_base::trunc . To znamená, že súbor sa vytvorí, ak neexistuje. Ak súbor existuje, jeho obsah bude vymazaný a samotný súbor bude pripravený na nahrávanie. Objekty triedy ifstream, keď sú spojené so súborom, majú štandardne režim otvárania súboru ios_base::in - súbor je otvorený len na čítanie. Režim otvárania súboru sa nazýva aj príznak, kvôli čitateľnosti budeme tento výraz používať aj v budúcnosti. Tabuľka 1 neuvádza všetky príznaky, ale na začiatok by vám mali stačiť.

Upozorňujeme, že príznaky ate a app sú veľmi podobné v popise, oba posúvajú ukazovateľ na koniec súboru, ale príznak app umožňuje zapisovať iba na koniec súboru a príznak ate jednoducho preusporiada príznak na koniec súboru a neobmedzuje priestor pre záznam.

Vytvorme program, ktorý pomocou operácie sizeof() vypočíta charakteristiky hlavných dátových typov v C++ a zapíše ich do súboru. Charakteristika:

  1. počet bajtov pridelených pre dátový typ
  2. maximálnu hodnotu, ktorú môže konkrétny typ údajov uložiť.

Zápis do súboru musí byť v nasledujúcom formáte:

/* dátový typ bajtov maximálna hodnota bool = 1 255,00 char = 1 255,00 krátka int = 2 32767,00 nepodpísané krátke int = 2 65535,00 int = 4 2147483647,00 nepodpísané int = 4 42949675,00 Long Int = 4 2147,00 dlhý plavák = 8 9223372036854775800,00 double = 8 9223372036854775800,00 */

Takýto program už bol vyvinutý skôr v tejto časti, ale tam boli všetky informácie o typoch údajov vyvedené na štandardné výstupné zariadenie a musíme program prerobiť tak, aby sa informácie zapisovali do súboru. Ak to chcete urobiť, musíte súbor otvoriť v režime zápisu s predbežným skrátením informácií o aktuálnom súbore ( riadok 14). Po vytvorení a úspešnom otvorení súboru (riadky 16 - 20) namiesto príkazu cout v riadok 22 použiť predmet fout. teda namiesto obrazovky sa do súboru zapíšu informácie o typoch údajov.

// write_file.cpp: definuje vstupný bod pre aplikáciu konzoly. #include "stdafx.h" #include #include // práca so súbormi #include // I/O manipulátory používajúce menný priestor std; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // prepojenie objektu so súborom, pričom sa súbor otvára v režime zápisu, pričom sa z neho najskôr vymažú všetky údaje z prúdu fout("data_types.txt ", ios_base::out | ios_base::trunc); if (!fout.is_open()) // ak súbor nebol otvorený ( cout<< "Файл не может быть открыт или создан\n"; // напечатать соответствующее сообщение return 1; // выполнить выход из программы } fout << " data type " << "byte" << " " << " max value "<< endl // nadpisy stĺpcov <<"bool = " << sizeof(bool) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных bool*/ << (pow(2,sizeof(bool) * 8.0) - 1) << endl << "char = " << sizeof(char) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных char*/ << (pow(2,sizeof(char) * 8.0) - 1) << endl << "short int = " << sizeof(short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных short int*/ << (pow(2,sizeof(short int) * 8.0 - 1) - 1) << endl << "unsigned short int = " << sizeof(unsigned short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned short int*/ << (pow(2,sizeof(unsigned short int) * 8.0) - 1) << endl << "int = " << sizeof(int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных int*/ << (pow(2,sizeof(int) * 8.0 - 1) - 1) << endl << "unsigned int = " << sizeof(unsigned int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned int*/ << (pow(2,sizeof(unsigned int) * 8.0) - 1) << endl << "long int = " << sizeof(long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long int*/ << (pow(2,sizeof(long int) * 8.0 - 1) - 1) << endl << "unsigned long int = " << sizeof(unsigned long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных undigned long int*/ << (pow(2,sizeof(unsigned long int) * 8.0) - 1) << endl << "float = " << sizeof(float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных float*/ << (pow(2,sizeof(float) * 8.0 - 1) - 1) << endl << "long float = " << sizeof(long float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long float*/ << (pow(2,sizeof(long float) * 8.0 - 1) - 1) << endl << "double = " << sizeof(double) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных double*/ << (pow(2,sizeof(double) * 8.0 - 1) - 1) << endl; fout.close(); // программа больше не использует файл, поэтому его нужно закрыть cout << "Данные успешно записаны в файл data_types.txt\n"; system("pause"); return 0; }

Nemožno si nevšimnúť, že zmeny v programe sú minimálne a to všetko vďaka tomu, že štandardný vstup/výstup a súborový vstup/výstup sa používajú úplne rovnakým spôsobom. Na konci programuriadok 45súbor sme výslovne uzavreli, aj keď sa to nevyžaduje, považuje sa to za dobrú programátorskú prax. Stojí za zmienku, že všetky funkcie a manipulátory používané na formátovanie štandardného vstupu/výstupu sú relevantné aj pre vstup/výstup súboru. Pri operátorovi sa teda nevyskytli žiadne chyby cout bol nahradený objektom fout.

Posledná aktualizácia: 31.10.2015

Na prácu s adresármi v mennom priestore System.IO sú navrhnuté dve triedy: Directory a DirectoryInfo .

Adresárová trieda

Trieda Directory poskytuje množstvo statických metód na správu adresárov. Niektoré z týchto metód sú:

    CreateDirectory(cesta) : vytvorí adresár na zadanej ceste

    Delete(path) : vymaže adresár na danej ceste

    Existuje(cesta) : Určuje, či adresár na zadanej ceste existuje. Ak existuje, vráti hodnotu true, ak nie, vráti hodnotu false.

    GetDirectories(cesta) : Získa zoznam adresárov v ceste

    GetFiles(path) : Získa zoznam súborov v adresárovej ceste

    Move(sourceDirName, destDirName): presunie adresár

    GetParent(path) : získa nadradený adresár

Trieda DirectoryInfo

Táto trieda poskytuje funkcie na vytváranie, odstraňovanie, presúvanie a iné operácie s adresármi. V mnohých ohľadoch je podobný adresáru. Niektoré z jeho vlastností a metód sú:

    Create() : vytvorí adresár

    CreateSubdirectory(path) : vytvorí podadresár na zadanej ceste

    Delete() : vymaže adresár

    Vlastnosť existuje: určuje, či adresár existuje

    GetDirectories() : Získa zoznam adresárov

    GetFiles() : získajte zoznam súborov

    MoveTo(destDirName) : presunie adresár

    Nadradená vlastnosť: získanie nadradeného adresára

    Vlastnosť root: získanie koreňového adresára

Pozrime sa na príklady použitia týchto tried

Získanie zoznamu súborov a podadresárov

string dirName = "C:\\"; if (Directory.Exists(dirName)) ( Console.WriteLine("Subdirectories:"); string dirs = Directory.GetDirectories(dirName); foreach (reťazec s v adresári) ( Console.WriteLine(s); ) Console.WriteLine( ); Console.WriteLine("Files:"); string files = Directory.GetFiles(dirName); foreach (reťazce v súboroch) ( Console.WriteLine(s); ) )

Všimnite si použitie lomiek v názvoch súborov. Buď použijeme dvojitú lomku: "C:\\" , alebo jednoduchú, ale potom dáme znak @ pred celú cestu: @"C:\Program Files"

Vytvorte adresár

string path = @"C:\SomeDir"; podcesta reťazca = @"program\avalon"; DirectoryInfo dirInfo = new DirectoryInfo (cesta); if (!dirInfo.Exists) ( dirInfo.Create(); ) dirInfo.CreateSubdirectory(podcesta);

Najprv skontrolujeme, či taký adresár existuje, pretože ak existuje, nebude možné ho vytvoriť a aplikácia vyhodí chybu. V dôsledku toho dostaneme nasledujúcu cestu: "C:\SomeDir\program\avalon"

Získanie informácií o adresári

string dirName = "C:\\Program Files"; DirectoryInfo dirInfo = new DirectoryInfo(dirName); Console.WriteLine($"Názov adresára: (dirInfo.Name)"); Console.WriteLine($"Úplný názov adresára: (dirInfo.FullName)"); Console.WriteLine($"Čas vytvorenia adresára: (dirInfo.CreationTime)"); Console.WriteLine($"Root Directory: (dirInfo.Root)");

Odstránenie adresára

Ak jednoducho aplikujeme metódu Delete na neprázdny priečinok, ktorý obsahuje nejaké súbory alebo podadresáre, potom aplikácia vyhodí chybu. Preto musíme do metódy Delete odovzdať ďalší parameter typu boolean, ktorý bude indikovať, že priečinok by sa mal odstrániť s celým obsahom:

String dirName = @"C:\SomeFolder"; try ( DirectoryInfo dirInfo = new DirectoryInfo(dirName); dirInfo.Delete(true); Console.WriteLine("Adresár odstránený"); ) catch (Exception ex) ( Console.WriteLine(ex.Message); )

String dirName = @"C:\SomeFolder"; Directory.Delete(dirName, true);

Presun adresára

string oldPath = @"C:\SomeFolder"; string newPath = @"C:\SomeDir"; DirectoryInfo dirInfo = new DirectoryInfo (stará cesta); if (dirInfo.Exists && Directory.Exists(newPath) == false) ( dirInfo.MoveTo(newPath); )

Pri presúvaní musíme počítať s tým, že nový adresár, do ktorého chceme presunúť všetok obsah starého adresára, nesmie existovať.

Na uľahčenie manipulácie sa informácie v úložných zariadeniach ukladajú vo forme súborov.

Súbor je pomenovaná oblasť externej pamäte vyhradenej na ukladanie poľa údajov. Údaje obsiahnuté v súboroch sú najrozmanitejšieho charakteru: programy v algoritmickom alebo strojovom jazyku; počiatočné údaje pre prevádzku programov alebo výsledky vykonávania programu; ľubovoľné texty; grafika atď.

Adresár (priečinok, adresár) – pomenovaná kolekcia bajtov na pamäťovom médiu obsahujúca názvy podadresárov a súborov, používaná v súborovom systéme na zjednodušenie organizácie súborov.

systém súborov je funkčná časť operačného systému, ktorá zabezpečuje operácie so súbormi. Príkladmi súborových systémov sú FAT (FAT - File Allocation Table, filelocation table), NTFS, UDF (používané na CD).

Existujú tri hlavné verzie FAT: FAT12, FAT16 a FAT32. Líšia sa bitovosťou záznamov v štruktúre disku, t.j. počet bitov pridelených na uloženie čísla klastra. FAT12 sa používa hlavne pre diskety (do 4 KB), FAT16 pre malé disky, FAT32 pre veľkokapacitné FLASH mechaniky (do 32 GB).

Zvážte štruktúru súborového systému pomocou FAT32 ako príklad.

Štruktúra súborov FAT32

Externé pamäťové zariadenia v systéme FAT32 nemajú bajtové, ale blokové adresovanie. Informácie sa zapisujú na externé pamäťové zariadenie v blokoch alebo sektoroch.

Sektor – minimálna adresovateľná jednotka ukladania informácií na externých pamäťových zariadeniach. Veľkosť sektora je zvyčajne pevne stanovená na 512 bajtov. Na zväčšenie adresného priestoru externých pamäťových zariadení sa sektory spájajú do skupín nazývaných klastre.

Klaster je združenie viacerých sektorov, ktoré možno považovať za samostatnú jednotku s určitými vlastnosťami. Hlavnou vlastnosťou klastra je jeho veľkosť, meraná počtom sektorov alebo počtom bajtov.

Systém súborov FAT32 má nasledujúcu štruktúru.

Klastre používané na zapisovanie súborov sú číslované od 2. Klaster č. 2 sa spravidla používa v koreňovom adresári a počnúc od klastra č. 3 sa ukladá dátové pole. Sektory používané na ukladanie informácií nad koreňovým adresárom nie sú zoskupené.
Minimálna veľkosť súboru na disku je 1 klaster.

Zavádzací sektor začína nasledujúcimi informáciami:

  • EB 58 90 - bezpodmienečná vetva a podpis;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 - počet bajtov v sektore (zvyčajne 512);
  • 1 bajt - počet sektorov v klastri;
  • 2 bajty - počet náhradných sektorov.

Okrem toho zavádzací sektor obsahuje nasledujúce dôležité informácie:

  • 0x10 (1 byte) – počet tabuliek FAT (zvyčajne 2);
  • 0x20 (4 bajty) - počet sektorov na disku;
  • 0x2C (4 bajty) – číslo klastra koreňového adresára;
  • 0x47 (11 bajtov) – označenie zväzku;
  • 0x1FE (2 bajty) - Podpis zavádzacieho sektora (55 AA).

Informačný sektor súborového systému obsahuje:

  • 0x00 (4 bajty) – podpis (52 52 61 41 );
  • 0x1E4 (4 bajty) – podpis (72 72 41 61 );
  • 0x1E8 (4 bajty) – počet voľných klastrov, -1, ak nie je známy;
  • 0x1EC (4 bajty) – číslo posledného zaznamenaného klastra;
  • 0x1FE (2 bajty) - podpis (55 AA).

Tabuľka FAT obsahuje informácie o stave každého klastra na disku. Spodné 2 bajty tabuľky FAT ukladajú F8 FF FF 0F FF FF FF FF (zodpovedá stavu klastrov 0 a 1, fyzicky chýbajú). Okrem toho stav každého klastra obsahuje číslo klastra, v ktorom aktuálny súbor pokračuje, alebo nasledujúce informácie:

  • 00 00 00 00 – klaster je voľný;
  • FF FF FF 0F je koniec aktuálneho súboru.
  • 8 bajtov - názov súboru;
  • 3 bajty - prípona súboru;

Koreňový adresár obsahuje množinu 32-bitových informačných záznamov pre každý súbor obsahujúci nasledujúce informácie:

Pri práci s dlhými názvami súborov (vrátane ruských názvov) je názov súboru zakódovaný v systéme kódovania UTF-16. V tomto prípade sú na kódovanie každého znaku pridelené 2 bajty. V tomto prípade je názov súboru napísaný vo forme nasledujúcej štruktúry:

  • 1 bajtová sekvencia;
  • 10 bajtov obsahuje spodných 5 znakov názvu súboru;
  • 1 bajtový atribút;
  • 1 bajt rezervovaný;
  • 1 bajt - kontrolný súčet názvu DOS;
  • 12 bajtov obsahuje spodné 3 znaky názvu súboru;
  • 2 bajty – číslo prvého klastra;
  • zvyšné znaky dlhého mena.

Práca so súbormi v C

Pre programátora je otvorený súbor reprezentovaný ako sekvencia dát, ktoré sa čítajú alebo zapisujú. Keď je súbor otvorený, je priradený k I/O tok. Výstupné informácie sa zapisujú do prúdu, vstupné informácie sa čítajú z prúdu.

Keď je prúd otvorený pre I/O, je spojený so štandardnou štruktúrou typu FILE, ktorá je definovaná v stdio.h. Štruktúra FILE obsahuje potrebné informácie o súbore.

Otvorenie súboru sa vykonáva pomocou funkcie fopen(), ktorá vracia ukazovateľ na štruktúru typu FILE , ktorú možno použiť na následné operácie so súborom.

SÚBOR *fopen(meno, typ);


name je názov súboru, ktorý sa má otvoriť (vrátane cesty),
typ je ukazovateľ na reťazec znakov, ktoré definujú spôsob prístupu k súboru:
  • "r" - otvorený súbor na čítanie (súbor musí existovať);
  • "w" - otvorte prázdny súbor na zápis; ak súbor existuje, jeho obsah sa stratí;
  • "a" - otvorený súbor na zápis do konca (na pripojenie); súbor sa vytvorí, ak neexistuje;
  • "r+" - otvorený súbor na čítanie a zápis (súbor musí existovať);
  • "w+" - otvorenie prázdneho súboru na čítanie a zápis; ak súbor existuje, jeho obsah sa stratí;
  • "a+" - otvorí súbor na čítanie a pridanie, ak súbor neexistuje, je vytvorený.

Návratová hodnota je ukazovateľ na otvorený stream. Ak sa nájde chyba, vráti sa NULL.

Funkcia fclose() zatvorí prúd alebo prúdy spojené so súbormi otvorenými pomocou fopen(). Prúd, ktorý sa má uzavrieť, je určený argumentom funkcie fclose().

Návratová hodnota: hodnota 0, ak bol prúd úspešne uzavretý; konštanta EOF, ak sa vyskytla chyba.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include
int main() (
SÚBOR *fp;
názov znaku = "my.txt" ;
if ((fp = fopen(meno, "r" )) == NULL )
{
printf( "Súbor sa nepodarilo otvoriť");
getchar();
návrat 0;
}
// otvorenie súboru bolo úspešné
... // požadované akcie s údajmi
fclose(fp);
getchar();
návrat 0;
}

Čítanie znaku zo súboru:

char fgetc(stream);


Argument funkcie je ukazovateľ na prúd typu FILE. Funkcia vráti kód načítaného znaku. Ak sa dosiahne koniec súboru alebo sa vyskytne chyba, vráti sa konštanta EOF.

Zápis znaku do súboru:

fputc(znak, stream);

Argumenty funkcie sú znak a ukazovateľ na prúd typu FILE . Funkcia vráti kód načítaného znaku.

Funkcie fscanf() a fprintf() sú podobné funkciám scanf() a printf(), ale pracujú s dátovými súbormi a ich prvým argumentom je ukazovateľ súboru.

fscanf(stream, "InputFormat" , args);