Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ
  • në shtëpi
  • Gabimet
  • Hapja e një skedari për të shkruar c. ofstream class: shkrimi i skedarëve

Hapja e një skedari për të shkruar c. ofstream class: shkrimi i skedarëve

Mekanizmi I / O i zhvilluar nga , nuk korrespondon me stilin e pranuar përgjithësisht të programimit të orientuar nga objekti sot, përveç kësaj, ai përdor në mënyrë aktive operacionet e treguesit, të cilat konsiderohen potencialisht të pasigurta në mjediset moderne të ekzekutimit të kodit të sigurt. Një alternativë për zhvillimin e aplikacioneve është mekanizmi standard i klasës I/O i ofruar nga standardi i gjuhës C++.

Hapja e skedarëve

Më së shpeshti përdoret klasat ifstream për lexim, ofstream për shkrim dhe fstream për modifikimin e skedarëve.

Të gjitha klasat e filetuara I/O rrjedhin në mënyrë indirekte nga paraardhësi i përbashkët ios, duke trashëguar plotësisht funksionalitetin e tij. Për shembull, anëtari i të dhënave të numëruara në modalitetin e hapur specifikon modalitetin e hapur të skedarit, i cili përcaktohet si më poshtë:

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

Më poshtë janë vlerat e mundshme flamujt dhe qëllimi i tyre.

Për shembull, për të hapur një skedar të quajtur test.txt për të lexuar të dhënat binare, duhet të shkruani:

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

Operatori logjik OR (|) ju lejon të kompozoni një modalitet me çdo kombinim flamujsh. Në mënyrë që kur hapni një skedar duke shkruar, të mos mbishkruani aksidentalisht një skedar ekzistues me të njëjtin emër, duhet të përdorni formularin e mëposhtëm:

skedar jashtë rrjedhës; file.open("test.txt", ios::out | ios::app);

Supozohet se projekti është i lidhur me të duhurin skedari i kokës:

#përfshi

Për të kontrolluar nëse skedari u hap me sukses, mund të përdorni konstruksionin

Nëse (! file) ( // Trajtimi i një gabimi të hapur të skedarit )

Operatorët e Përfshirjes dhe Nxjerrjes

E anashkaluar në klasat e trajtimit të skedarëve përfshijnë operatorin (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

Skedari<< "Это строка текста";

Ju gjithashtu mund të shkruani një varg teksti në pjesë:

Skedari<< "Это " << "строка " << "текста";

Deklarata endl përfundon hyrjen e linjës me një kthim të transportit:

Skedari<< "Это строка текста" << endl;

Duke përdorur operatorin e përfshirjes, është e lehtë të shkruani vlerat e variablave ose elementëve të grupit në një skedar:

Skedari jashtë rrjedhës ("Temp.txt"); char buff = "Rreth teksti përmban variabla"; int vx = 100; float pi = 3,14159; dosje<< buff << endl << vx << endl << pi << endl;

Si rezultat i ekzekutimit të kodit, krijohen tre rreshta të skedarit të tekstit Temp.txt:

Vargu teksti përmban variabla 100 3.14159

Vini re se vlerat numerike shkruhen në skedar si vargje teksti, jo si vlera binare.

operatori i ekstraktit(>>) bën të kundërtën. Duket se për të nxjerrë karakteret nga skedari Temp.txt i shkruar më herët, duhet të shkruani kodin si më poshtë:

skedari ifstream ("Temp.txt"); char buff; intvx; floatpi; skedar >> buff >> vx >> pi;

Megjithatë, operatori i nxjerrjes do të ndalet në kufirin e parë (hapësirën, skedën ose linjën e re) që has. Kështu, kur analizohet fjalia "Tekst array përmban variabla", vetëm fjala "Text" do t'i shkruhet array buff, hapësira shpërfillet dhe fjala "array" do të bëhet vlera e ndryshores së plotë vx dhe kodit. ekzekutimi do të "bëhet i pakëndshëm" me një shkelje të pashmangshme të strukturës së të dhënave. Më pas, kur diskutojmë klasën ifstream, do të tregojmë se si të organizojmë saktë leximin e skedarit nga shembulli i mëparshëm.

klasa ifstream: leximi i skedarëve

Siç nënkupton edhe emri, klasa ifstream është krijuar për të futur një transmetim skedari. Metodat kryesore të klasës janë renditur më poshtë. Shumica e tyre janë trashëguar nga klasa istream dhe janë të mbingarkuara me funksionalitetin prind. Për shembull, funksioni marrë, në varësi të parametrit të thirrjes, është në gjendje të lexojë jo vetëm një karakter të vetëm, por edhe një bllok karakteresh.

Tani është e qartë se si duhet të modifikoni shembullin e mëparshëm në mënyrë që përdorimi i operatorit të nxjerrjes së të dhënave të japë rezultatin e pritur:

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

Metoda getline do të lexojë rreshtin e parë të skedarit deri në fund, dhe operatori >> do t'u caktojë vlera variablave.

Shembulli i mëposhtëm tregon shtimin e të dhënave në skedar teksti pasuar nga leximi i të gjithë dosjes. ndërsa lak(1) përdoret në vend të while(!file2.eof()) për arsye të diskutuara në .

#përfshi #përfshi duke përdorur hapësirën e emrave std; int main() ( file ofstream; file.open ("test.txt",ios::out|ios::app); if (!file) (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; nëse (skedari2.eof()) thyhet; cout<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

Shembulli i mëposhtëm kalon përmes leximit të rreshtave nga skedari test.txt dhe shfaqjes së tyre në tastierë.

#përfshi #përfshi duke përdorur hapësirën e emrave std; int main() ( skedari ifstream; // krijoni një skedar skedari të objektit të transmetimit.open("test.txt"); // hap skedarin për lexim nëse (!file) kthen 1; // kthej gabimin në hapjen e char str;/ / tampon linja statike // Lexoni dhe shfaqni linjat në një lak deri në eof ndërsa (!file.getline(str, sizeof(str)).eof()) cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

Ky kod nën Windows OS varet gjithashtu nga prania e një karakteri të linjës së re në rreshtin e fundit të skedarit, do të ishte më e besueshme ta bëni këtë:

Ndërsa (1) ( if (file.eof()) thyen; file.getline(str, sizeof(str)); cout<< str << endl; }

Thirrjet e qarta në metodat e hapjes dhe mbylljes janë opsionale. Në të vërtetë, thirrja e konstruktorit me një argument ju lejon të hapni skedarin menjëherë, në momentin që krijohet objekti i transmetimit të skedarit:

skedari ifstream ("test.txt");

Në vend të metodës së mbylljes, mund të përdorni operatorin e fshirjes, i cili automatikisht do të thërrasë destruktorin e objektit të skedarit dhe do të mbyllë skedarin. Kodi i ciklit while siguron kontrollin e duhur të fundit të skedarit.

ofstream class: shkrimi i skedarëve

Klasa ofstream është krijuar për të nxjerrë të dhëna nga një rrjedhë skedari. Metodat kryesore të kësaj klase janë renditur më poshtë.

Operatori i përfshirjes i përshkruar më herët është i përshtatshëm për organizimin e shkrimit në një skedar teksti:

Skedari jashtë rrjedhës ("temp.txt"); nëse (!skedari) kthehet; për (int i=1; i<=3; i++) file << "Строка " << i << endl; file.close();

Binarët

Në parim, të dhënat binare shërbehen si të dhëna teksti. Dallimi është se nëse të dhënat binare shkruhen në një strukturë të caktuar logjike, atëherë ato duhet të lexohen nga skedari në një variabël të të njëjtit lloj strukture.

Parametri i parë i metodave të shkrimit dhe leximit (adresa e bllokut shkrim/lexim) duhet të jetë i tipit të treguesit të karakterit char * , kështu që është e nevojshme të konvertohet në mënyrë eksplicite lloji i adresës së strukturës void *. Parametri i dytë specifikon që blloqet binare të skedarit kanë një madhësi konstante bajt, pavarësisht nga gjatësia aktuale e regjistrimit. Shtojca e mëposhtme jep një shembull se si të krijohen dhe shfaqen të dhënat në një fletore të thjeshtë. Të dhënat e skedarit lexohen më pas në mënyrë sekuenciale dhe shfaqen në tastierë.

#përfshi #përfshi #përfshi duke përdorur hapësirën e emrave std; struct Shënime ( // struktura e të dhënave të fletores char Emri; // emri i plotë char Telefoni; // telefon int Mosha; // mosha ); int main() ( setlocale (LC_ALL, "Rusisht"); Shënime Shënim1= ("Grozny Ioann Vasilyevich", "jo i instaluar", 60); Shënime Shënim2= ("Godunov Boris Fedorovich", "095-111-2233 ", 30 ); Shënime Shënim3= ( "Peter Romanov ", "812-333-2211 ", 20 ); ofile ("Notebook.dat", ios::binary); ofile.write((char*)&Note1, sizeof ( Shënime)); // Blloku i parë ofile.write((char*)&Note2, sizeof(Shënime)); // Blloku i dytë ofile.write((char*)&Note3, sizeof(Shënime)); / / Blloku i 3-të i ofile. close(); // mbyll skedarin e shkruar ifstream ifile ("Notebook.dat", ios::binary); Shënime Shënim; // variabla e strukturuar char str; // buffer string statik // Lexoni dhe shfaqni linjat në një lak derisa eof while (!ifile.read((char*)&Note, sizeof(Notes)).eof()) ( sprintf(str, "%s\tTrupi: %s\tMosha: %d" , Shënim.Emri, Shënim. Telefon, Shënim. Mosha); cout<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

Si rezultat i ekzekutimit të këtij kodi, një skedar binar Notebook.dat formohet nga tre blloqe me nga 80 bajt secili (duke supozuar se karakteret janë me një bajt). Natyrisht, mund të përdorni metoda të tjera transmetimi dhe të kryeni çdo operacion në fushat e një strukture të caktuar të të dhënave.

Klasa fstream: akses i rastësishëm i skedarëve

Supozoni se fletorja jonë ka grumbulluar 100 shënime dhe ne duam të numërojmë të 50-tën. Sigurisht, mund të organizoni një lak dhe të lexoni të gjitha regjistrimet nga i pari në atë të dhënë. Natyrisht, një zgjidhje më e synuar është të vendosni treguesin e pozicionit të skedarit pos drejtpërdrejt në hyrjen 50 dhe ta lexoni atë:

ifstream ifile("Notebook.dat", ios::binary); int pos = 49 * sizeof(Shënime); ifile seek(pos); // kërko për hyrjen e 50-të Shënime Shënim; //Shënime - struktura "record" e përshkruar më sipër ifile.read((char*)&Note, sizeof(Notes));

Operacione të tilla kërkimi janë efektive nëse skedari përbëhet nga regjistrime të një madhësie të njohur dhe konstante. Për të zëvendësuar përmbajtjen e një hyrje arbitrare, duhet të hapni rrjedhën e daljes në modalitetin e modifikimit:

Ofile ("Notebook.dat", ios::binary | ios::ate); int pos = 49 * sizeof(Shënime); ofile seekp(pos); // kërkoni për shënimin e 50-të Shënime Shënim50 = ("Yeltsin Boris Nikolaevich", "095-222-3322", 64); ofile.write((char*)&Shënim, sizeof(Shënime)); // zëvendësim

Nëse nuk e specifikoni flamurin ios::ate (ose ios::app), atëherë kur hapni skedarin binar Notebook.dat, përmbajtja e tij e mëparshme do të fshihet!

Së fundi, është e mundur të hapet një skedar njëkohësisht për lexim/shkrim, duke përdorur metoda të trashëguara nga klasa e transmetimit fstream nga paraardhësit e saj. Meqenëse klasa fstream rrjedh nga istream dhe ostream (prindërit e ifstream dhe ofstream respektivisht), të gjitha metodat e përmendura më parë bëhen të disponueshme për aplikacionin.

Shembulli i mëposhtëm ndërron hyrjen e parë dhe të tretë në skedarin Notebook.dat.

#përfshi #përfshi #përfshi duke përdorur hapësirën e emrave std; struct Shënime ( char Emri; char Phone; int Age; ); int main() ( setlocale(LC_ALL, "Rusisht"); Shënime Shënim1, Shënim3; // Hap skedarin për lexim/shkrim njëkohësisht skedar fstream("Notebook.dat", ios::binary | ios::in | ios:: jashtë); file.seekg (2 * sizeof(Shënime)); // gjeni dhe lexoni skedarin Note3.read((char*)&Note3, sizeof(Shënime)); file.seekg(0); // gjeni dhe lexoni Shënimin1 file.read((char*)&Note1, sizeof(Shënime)); file.seekg(0); // Shënim1<== 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; }

Flamujt ios::in dhe ios::out duhet të specifikohen në konstruktorin e objektit të skedarit për të lejuar operacione të njëkohshme leximi dhe shkrimi. Si rezultat i ekzekutimit të këtij kodi, të dhënat e para dhe të treta të skedarit binar Notebook.dat do të shkëmbehen.

Ka shembuj shtesë për këtë temë.

- krahasimi për të identifikuar barazinë ose pabarazinë.

Qëllimi praktik i një numërimi është të përcaktojë një grup konstantesh simbolike të dallueshme të një lloji të plotë.

Një shembull i përdorimit të variablave të numëruar:

mo=1, tu, ne, th, fr, sa, su ) ditë;

puts(“ Fut ditën e javës (nga 1 në 7) : ”); scanf("%d", &t_day);

w_ditë=su; start = mo;

fund = w_ditë -t_ditë;

printf("\n e hëna është %dth dita e javës, \ tani është %dth dita. \n\

Deri në fund të javës %d ditë (ditë). ”, fillimi, t_dita, fundi);

Rezultati i programit: Shkruani ditën e javës (nga 1 deri në 7): 2

E hëna është dita e parë e javës, tani dita e 2-të. Deri në fund të javës 5 ditë (ditë).

18. Skedarët në gjuhën C

Një skedar është një grup të dhënash të vendosura në një medium të jashtëm dhe të konsideruara si një e tërë gjatë përpunimit. Skedarët përmbajnë të dhëna të destinuara për ruajtje afatgjatë.

Ekzistojnë dy lloje skedarësh: tekst dhe binar. Skedarët e tekstit janë një sekuencë karakteresh ASCII dhe mund të shikohen dhe modifikohen me çdo redaktues teksti.

Skedarët binare (binare) janë një sekuencë të dhënash, struktura e të cilave përcaktohet nga softueri.

Gjuha C ka një grup të madh funksionesh për të punuar me skedarë, shumica e të cilave gjenden në bibliotekat stdio.h dhe io.h.

18.1. Hapja e një skedari

Çdo skedari i caktohet një emër logjik i brendshëm, i cili përdoret më vonë kur i referohet. Emri logjik (ID e skedarit) është

treguesi i skedarit, d.m.th. në një zonë memorie që përmban të gjithë informacionin e nevojshëm në lidhje me skedarin. Formati për deklarimin e një treguesi skedari është si më poshtë:

FILE * tregues për një skedar;

FILE është një identifikues i tipit strukturor, i përshkruar në bibliotekën standarde

stdio.h dhe që përmban informacionin e mëposhtëm:

shkruani struct(

– numri i bajteve të palexuara të mbetura në bufer;

madhësia e zakonshme e buferit është 512 bajt; sapo niveli=0,

blloku tjetër i të dhënave lexohet në bufer nga skedari;

– flamuri i statusit të skedarit – lexim, shkrim, shtim;

– përshkruesi i skedarit, d.m.th. numri që e përcakton atë

char mbajë e panënshkruar;

– karakter i patransmetuar, d.m.th. ungetc-simbol;

– madhësia e tamponit të ndërmjetëm të brendshëm;

tampon char i panënshkruar;

është vlera e treguesit që duhet aksesuar brenda buferit, d.m.th.

specifikon fillimin e buferit, fillimin e rreshtit ose vlerën aktuale

vlera e treguesit brenda buferit në varësi të modalitetit

ma buffering;

i panënshkruar char *curp;

është vlera aktuale e treguesit për akses brenda buferit

fera, d.m.th. vendos pozicionin aktual në buferin e shkëmbimit

në vazhdim me programin;

stem i panënshkruar;

– flamuri i skedarit të përkohshëm;

– flamur kur punoni me një skedar;

) DOSJE;

Para se të filloni të punoni me skedarin, d.m.th. për të qenë në gjendje të lexoni ose shkruani informacion në një skedar, ai duhet të hapet për qasje. Kjo zakonisht bëhet duke përdorur funksionin

FILE* fopen(char* emri i skedarit, char* modaliteti);

merr një paraqitje të jashtme - emrin fizik të skedarit në media (disketë, hard disk) dhe i cakton një emër logjik.

Emri fizik, d.m.th. emri i skedarit dhe rruga drejt tij jepet nga parametri i parë

– një varg, për shembull, "a:Mas_dat.dat" është një skedar me emrin Mas_dat.dat i vendosur në një disketë, "d:\\work\\Sved.txt" është një skedar me emrin Sved.txt i vendosur në një hard disk. drive në drejtorinë e punës.

Kujdes! Viza e prapme (\), si karakter special, shkruhet dy herë në një varg.

Pas hapjes me sukses, funksioni fopen kthen një tregues skedari (në tekstin e mëtejmë referuar si treguesi i skedarit). Në rast gabimi, NULL kthehet. Kjo situatë zakonisht ndodh kur shtegu i skedarit që hapet është specifikuar gabimisht. Për shembull, nëse specifikoni një shteg në klasën e ekranit të universitetit tonë që është e ndaluar për t'u shkruar (zakonisht lejohet d:\work\).

Parametri i dytë është një varg që specifikon mënyrën e hyrjes në skedar:

w - skedari hapet për shkrim; nëse nuk ka skedar me emrin e dhënë, ai do të krijohet; nëse ekziston një skedar i tillë, atëherë informacioni i mëparshëm shkatërrohet para hapjes;

r - skedari hapet vetëm për lexim; nëse nuk ka një skedar të tillë, atëherë ndodh një gabim;

a - skedari hapet për të shtuar informacion të ri në fund;

r+ - skedari hapet për redaktimin e të dhënave - informacioni për shkrimin dhe leximin është i mundur;

w+ është i njëjtë si për r+;

a+ - njësoj si për a, vetëm shkrimi mund të kryhet kudo në skedar; leximi i skedarëve është gjithashtu i disponueshëm;

t - skedari hapet në modalitetin e tekstit; b - skedari hapet në modalitetin binar.

Modaliteti i tekstit ndryshon nga ai binar në atë që kur hapet një skedar si një çift karakteresh teksti "ushqimi i linjës", "kthimi i transportit" zëvendësohet nga një karakter: "ushqimi i linjës" për të gjitha funksionet e shkrimit të të dhënave në skedar, dhe për të gjitha funksionet e daljes, karakteri "line feed" "" zëvendësohet tani me dy karaktere: "line feed", "carriage kthim".

Si parazgjedhje, skedari hapet në modalitetin e tekstit. Shembull: FILE *f; – deklarohet një tregues në skedarin f;

f = fopen("d:\\work\\Dat_sp.cpp", "w"); – hapet për të shkruar një skedar me emrin logjik f, me emrin fizik Dat_sp.cpp, i vendosur në diskun d, në dosjen e punës; ose më shkurt

FILE *f = fopen("d:\\work\\Dat_sp.cpp", "w");

18.2. Mbyllja e një skedari

Pas punës me skedarin, qasja në të duhet të mbyllet. Kjo realizohet nga funksioni int fclose (treguesi i skedarit). Për shembull, nga shembulli i mëparshëm, skedari mbyllet kështu: fclose (f);

Për të mbyllur skedarë të shumtë, është prezantuar një funksion, i deklaruar si më poshtë: void fcloseall(void );

Nëse dëshironi të ndryshoni modalitetin e hyrjes në skedar, atëherë fillimisht duhet të mbyllni skedarin dhe më pas ta rihapni atë, por me të drejta të ndryshme aksesi. Për ta bërë këtë, përdorni funksionin standard:

FILE* freopen (char*filename , char *mode , FILE *filepointer );

Ky funksion fillimisht mbyll skedarin e deklaruar treguesi i skedarit(siç bën funksioni fopen) dhe më pas hap skedarin me lejet e emrit të skedarit dhe "mode".

Gjuha C ka aftësinë për të punuar me skedarë të përkohshëm që nevojiten vetëm gjatë funksionimit të programit. Në këtë rast, funksioni përdoret

FILE*tmpfile(void);

i cili krijon një skedar të përkohshëm në disk me leje “w+b”, pasi programi përfundon ose pasi skedari i përkohshëm është mbyllur, ai fshihet automatikisht.

18.3. Shkrim - lexim informacioni

Të gjitha veprimet për leximin dhe shkrimin e të dhënave në një skedar mund të ndahen në tre grupe: operacione hyrje-dalje karakter pas karakteri; operacionet hyrëse/dalëse të linjës; bllokojnë operacionet hyrëse/dalëse.

Konsideroni funksionet kryesore të përdorura në secilin prej këtyre tre grupeve të operacioneve.

Karakteri I/O

Funksionet I/O të karaktereve pranojnë një karakter të vetëm nga një skedar ose transferojnë një karakter të vetëm në një skedar:

Rreshti I/O

Funksionet e linjës I/O transferohen nga një skedar ose në

Blloko I/O

Funksionet e bllokut I/O funksionojnë në blloqe të tëra

informacion:

int fread (void*p, intsize,

- lexon n blloqe me madhësi bajte secilin prej skedarëve

int n, FILE *f)

la f në zonën e kujtesës me treguesin p (nevoja

int fwrite(void*p, intsize,

caktoni memorie paraprakisht për bllokun që lexohet);

– shkruan n blloqe me madhësi bajte secili prej tyre

int n, FILE *f)

vendndodhja e memories me treguesin p në skedarin f.

I/O e formatuar prodhohet nga funksionet.

Para kësaj, gjatë futjes dhe daljes së të dhënave, ne kemi punuar me transmetime standarde - tastierë dhe monitor. Tani le të shohim se si gjuha C zbaton marrjen e të dhënave nga skedarët dhe shkrimin e tyre atje. Përpara kryerjes së këtyre veprimeve, skedari duhet të hapet dhe të aksesohet.

Në gjuhën e programimit C, një tregues skedari është i tipit FILE dhe deklarata e tij duket si kjo:
FILE *myfile;

Nga ana tjetër, funksioni fopen() hap skedarin në adresën e specifikuar si argumenti i parë në modalitetin read ("r"), shkrim ("w") ose shtoj ("a") dhe i kthen një tregues. ndaj programit. Prandaj, procesi i hapjes së një skedari dhe lidhjes së tij me programin duket diçka si kjo:
myfile = fopen ("hello.txt", "r");

Kur lexoni ose shkruani të dhëna në një skedar, ai aksesohet përmes një treguesi skedari (në këtë rast, myfile).

Nëse për ndonjë arsye (nuk ka skedar në adresën e specifikuar, qasja në të refuzohet) funksioni fopen() nuk mund ta hapë skedarin, atëherë ai kthen NULL. Në programet reale, gabimi i hapjes së një skedari trajtohet pothuajse gjithmonë në degën if, por ne do ta lëmë këtë më tej.

Deklarata e funksionit fopen() gjendet në skedarin e kokës stdio.h, kështu që kërkohet përfshirja e tij. Lloji i strukturës FILE është deklaruar edhe në stdio.h.

Pas përfundimit të punës me skedarin, është zakon që ta mbyllni atë për të çliruar buferin nga të dhënat dhe për arsye të tjera. Kjo është veçanërisht e rëndësishme nëse programi vazhdon të funksionojë pas punës me skedarin. Thyerja e lidhjes midis një skedari të jashtëm dhe një treguesi në të nga programi bëhet duke përdorur funksionin fclose(). Ai merr një tregues skedari si parametër:
fclose (myfile);

Më shumë se një skedar mund të hapet në program. Në një rast të tillë, çdo skedar duhet të shoqërohet me treguesin e tij të skedarit. Megjithatë, nëse programi fillimisht punon me një skedar, pastaj e mbyll atë, atëherë treguesi mund të përdoret për të hapur një skedar të dytë.

Leximi nga dhe shkrimi në një skedar teksti

fscanf ()

Funksioni fscanf() është i ngjashëm në kuptim me funksionin scanf(), por ndryshe nga ai, ai merr hyrje të formatuar nga një skedar dhe jo hyrje standarde. Funksioni fscanf() merr parametrat: treguesin e skedarit, vargun e formatit, adresat e zonave të memories për shkrimin e të dhënave:
fscanf(myfile, "%s%d", str, &a);

Kthen numrin e të dhënave të lexuara me sukses, ose EOF. Hapësirat, karakteret e linjës së re merren parasysh si ndarës të të dhënave.

Le të themi se kemi një skedar që përmban përshkrimin e mëposhtëm të objekteve:

Mollë 10 23,4 banane 5 25,0 bukë 1 10,3

#përfshi main () ( FILE * file; struct food ( char emri[ 20 ] ; sasia e panënshkruar; çmimi float; ) ; struct food shop[ 10 ] ; char i= 0 ; file = fopen ("fscanf.txt" , "r" ) ; ndërsa (fscanf (skedari, "%s%u%f" , shop[ i] .emri , & (dyqan[ i] .qty ) , & (dyqan[ i] .çmimi ) ) != EOF) ( printf ("%s %u %.2f \n", dyqan[ i] .emër , dyqan[ i] .sasi , dyqan[ i] .çmimi ); i++; ) )

Në këtë rast, deklarohen një strukturë dhe një grup strukturash. Çdo rresht nga skedari korrespondon me një element të grupit; një element vargu është një strukturë që përmban një varg dhe dy fusha numerike. Cikli lexon një rresht për përsëritje. Kur ndeshet fundi i skedarit, fscanf() kthen EOF dhe cikli përfundon.

fgets ()

Funksioni fgets() është i ngjashëm me funksionin gets() dhe kryen hyrjen rresht pas rreshti nga një skedar. Një thirrje në fgets() do të lexojë një rresht. Në këtë rast, nuk mund të lexoni të gjithë rreshtin, por vetëm një pjesë të tij nga fillimi. Opsionet e fgets () duken kështu:
fgets (vargu_karakterash, numri_i_karaktereve_për_lexim, treguesi_tek_skedari)

Për shembull:
fgets (str, 50, myfile)

Një thirrje e tillë funksioni do të lexojë nga skedari i lidhur me treguesin myfile një rresht teksti të plotë nëse gjatësia e tij është më pak se 50 karaktere, duke përfshirë karakterin "\n", të cilin funksioni do ta ruajë gjithashtu në grup. Elementi i fundit (50) i grupit str do të jetë karakteri "\0" i shtuar nga fgets() . Nëse vargu është më i gjatë, funksioni do të lexojë 49 karaktere dhe do të shkruajë "\0" në fund. Në këtë rast, "\n" nuk do të përmbahet në rreshtin e leximit.

#përfshi #define N 80 kryesore () ( FILE * skedar; char arr[ N] ; skedar = fopen ("fscanf.txt" , "r" ) ; ndërsa (fgets (arr, N, skedar) != NULL) printf (" %s" , arr) ; printf(" \n") ; fclose(file); )

Në këtë program, ndryshe nga ai i mëparshmi, të dhënat lexohen rresht pas rreshti në grupin arr. Kur lexohet rreshti tjetër, ai i mëparshmi humbet. Funksioni fgets() kthen NULL nëse nuk mund të lexojë rreshtin tjetër.

getc () ose fgetc ()

Funksioni getc() ose fgetc() (të dyja funksionojnë) ju lejon të merrni karakterin tjetër nga skedari.

ndërsa ((arr[ i] = fgetc (skedar) ) != EOF) ( nëse (arr[ i] == " \n") ( arr[i] = " \0 " ; printf("%s \n", arr) ; i = 0 ) tjetër i++; ) arr[i] = " \0 " ; printf("%s \n", arr) ;

Kodi i dhënë si shembull printon të dhënat nga një skedar në ekran.

Shkrimi në një skedar teksti

Ashtu si hyrja, dalja në një skedar mund të jetë e ndryshme.

  • Prodhimi i formatuar. Funksioni fprintf (pointer_file, format_string, variables) .
  • Post output. Funksioni fputs (string, filepointer) .
  • Prodhimi simbolik. fputc() ose putc(karakter, tregues skedari).

Më poshtë janë shembuj kodesh që përdorin tre mënyra për të nxjerrë të dhëna në një skedar.

Shkrimi në çdo rresht të skedarit të fushës së një strukture:

file = fopen("fprintf.txt", "w"); while (scanf ("%s%u%f" , shop[ i] .emri , & (dyqan[ i] .qty ) , & (dyqan[ i] .çmimi ) ) != EOF) ( fprintf (skedar, " %s %u %.2f \n", dyqan[ i] .emër , dyqan[ i] .sasi , dyqan[ i] .çmimi ); i++; )

Dalja rresht pas rreshti në një skedar (fputs() , ndryshe nga vetë puts(), nuk vendos "\n" në fund të rreshtit):

ndërsa (merr (arr) != NULL) (fputs (arr, skedar) ; fputs (" \n", skedar); )

Një shembull i daljes karakter pas karakteri:

ndërsa ((i = getchar () ) != EOF) putc (i, skedar) ;

Leximi nga dhe shkrimi në një skedar binar

Ju mund të punoni me një skedar jo si një sekuencë karakteresh, por si një sekuencë bajtash. Në parim, është e pamundur të punosh me skedarë jo tekst në një mënyrë tjetër. Megjithatë, ju gjithashtu mund të lexoni dhe shkruani në skedarë teksti në këtë mënyrë. Avantazhi i kësaj metode për të hyrë në një skedar qëndron në shpejtësinë e leximit-shkrimit: një bllok i konsiderueshëm informacioni mund të lexohet / shkruhet në një akses.

Kur hapni një skedar për qasje binar, argumenti i dytë për fopen() është vargu "rb" ose "wb".

Tema e punës me skedarë binare është mjaft komplekse, kërkon një mësim të veçantë për ta studiuar atë. Këtu do të shënohen vetëm veçoritë e funksioneve të leximit dhe shkrimit në një skedar, i cili konsiderohet si një rrjedhë bajtash.

Funksionet fread() dhe fwrite() marrin si parametra:

  1. adresa e zonës së memories nga ku shkruhen ose lexohen të dhënat,
  2. madhësia e një të dhënë të çdo lloji,
  3. sasinë e të dhënave që duhen lexuar për madhësinë e specifikuar,
  4. treguesi i skedarit.

Këto funksione kthejnë numrin e të dhënave të lexuara ose të shkruara me sukses. Ato. ju mund të "porositni" leximin e 50 elementeve të të dhënave, dhe të merrni vetëm 10. Nuk do të ketë asnjë gabim.

Një shembull i përdorimit të funksioneve fread() dhe fwrite():

#përfshi #përfshi main () ( FILE * skedar; char shelf1[ 50 ] , shelf2[ 100 ] ; int n, m; file = fopen ("shelf1.txt" , "rb" ) ; n= fread (raft1, madhësia e (char) , 50 , skedar) ; fclose (skedar) ; skedar = fopen ("shelf2.txt", "rb"); m= fread (raft2, madhësia e (char) , 50, skedari) ; fclose (skedar) ; raft1[ n] = " \0 " ; raft 2[m] = " \n"; raft2[ m+ 1 ] = " \0 " ; file = fopen("shop.txt" , "wb"); fwrite (strcat (raft2, raft1) , madhësia e (char ) , n+ m, skedar) ; fclose(file); )

Këtu tentohet të lexohen 50 karaktere nga skedari i parë. n ruan numrin e karaktereve të lexuara në të vërtetë. Vlera e n mund të jetë 50 ose më pak. Të dhënat vendosen në një varg. E njëjta gjë ndodh me skedarin e dytë. Më pas, rreshti i parë i bashkëngjitet rreshtit të dytë dhe të dhënat hidhen në skedarin e tretë.

Zgjidhja e problemeve

  1. Shkruani një program që i kërkon përdoruesit emrin (adresën) e një skedari teksti, pastaj e hap atë dhe numëron numrin e karaktereve dhe rreshtave në të.
  2. Shkruani një program që shkruan në një skedar të dhëna të marra nga një skedar tjetër dhe të modifikuara në një mënyrë ose në një tjetër përpara se të shkruhen. Çdo rresht i të dhënave të marra nga skedari duhet të vendoset në një strukturë.

Skedarët e tekstit

Le të shqyrtojmë punën me një skedar teksti në C duke përdorur një shembull. Krijo një skedar teksti në diskun C të quajtur TextFile.txt. Shkruani rreshtat e mëposhtëm në këtë skedar:

Vargu_1 123 Vargu_11, 456
Vargu_2
Vargu_3

Ruani skedarin.

Dhe ky është kodi për programin C që hap skedarin tonë dhe lexon rreshta prej tij:

/* *Autor: @autor Subbotin B.P..h> #include #define LEN 50 int main(void) ( puts ("Operacionet e skedarit të tekstit"); char cArray; FILE *pTextFile = fopen ("C:\\TextFile.txt", "r"); if(pTextFile == NULL) ( puts("Problems"); kthe EXIT_FAILURE; ) while(fgets(cArray, LEN, pTextFile) != NULL) ( printf("%s", cArray); ) fclose(pTextFile); kthe EXIT_SUCCESS; )

Për të hapur një skedar teksti në C, përdorni funksionin fopen:

FILE *pTextFile = fopen("C:\\TextFile.txt", "r");

Argumenti i parë për funksionin fopen tregon një skedar, dhe i dyti thotë se skedari është i hapur për t'u lexuar prej tij.

Ne lexojmë rreshtat duke përdorur funksionin fgets:

fgets (cArray, LEN, pTextFile);

Argumenti i parë i funksionit fgets tregon një grup karakteresh në të cilat do të ruhen vargjet e marra, argumenti i dytë është numri maksimal i karaktereve për t'u lexuar, i treti është skedari ynë.

Pasi të përfundoni punën me skedarin, duhet ta mbyllni atë:

fclose(pTextFile);

Ne marrim:

Shkronjat ruse në rreshta kalojnë gjithashtu.

Nga rruga, unë e bëra këtë program në Eclipse. Mund të shihni se si të punoni me C/C++ në Eclipse.

Pra, ne hapëm dhe lexuam të dhënat nga një skedar teksti.

Tani le të mësojmë se si të krijojmë në mënyrë programore një skedar teksti dhe të shkruajmë të dhëna në të.

/* Autori: @autor Subbotin B.P..h> #include int main(void) ( FILE *pTextFile = fopen("C:\\TextFileW.txt", "w"); char *cString = "Ky është një varg"; char cNewLine = "\n"; int nVal = 123 ; if(pTextFile == NULL) ( vendos ("Problemet"); kthe EXIT_FAILURE; ) fprintf(pTextFile, "%s%c", cString, cNewLine); fprintf(pTextFile, "%d", nVal); kthe EXIT_SUCCESS ;)

Krijo një skedar teksti për të shkruar të dhëna në të:

FILE *pTextFile = fopen("C:\\TextFileW.txt", "w");

nëse skedari ekziston tashmë, ai do të hapet dhe të gjitha të dhënat do të fshihen prej tij.

Vargu C cString dhe numri nVal shkruhen nga programi në një skedar teksti. cNewLine është vetëm një ndërprerje e linjës.

Ne shkruajmë të dhëna në një skedar teksti duke përdorur funksionin fprintf:

fprintf(pTextFile, "%s%c", cString, cNewLine);

argumenti i parë këtu është skedari ynë, i dyti është vargu i formatit, i treti ose më shumë është numri i argumenteve të nevojshme për këtë format.

Artikujt kryesorë të lidhur