Kako podesiti pametne telefone i računare. Informativni portal
  • Dom
  • vijesti
  • Rad sa dva fajla c. Pisanje - čitanje informacija

Rad sa dva fajla c. Pisanje - čitanje informacija

Radi lakšeg snalaženja, informacije u uređajima za pohranu pohranjuju se u obliku datoteka.

Fajl - imenovano područje eksterna memorija namjenski za pohranjivanje niza podataka. Podaci sadržani u datotekama su najrazličitije prirode: programi bazirani na algoritamskom ili mašinski jezik; početni podaci za rad programa ili rezultati izvođenja programa; proizvoljnih tekstova; grafičke slike itd.

Direktorij (fascikla, direktorij) - imenovana kolekcija bajtova na mediju za pohranu, koja sadrži nazive poddirektorija i datoteka, koristi se u sistemu datoteka kako bi se pojednostavila organizacija datoteka.

Sistem podataka nazvan funkcionalnim dijelom operativni sistem, koji omogućava izvršavanje operacija nad datotekama. Primjeri sistema datoteka su FAT (FAT - Tabela dodjeljivanja datoteka), NTFS, UDF (koristi se na CD-ovima).

Postoje tri glavne verzije FAT-a: FAT12, FAT16 i FAT32. Razlikuju se po dubini bita zapisa u strukturi diska, tj. broj bitova dodijeljenih za pohranjivanje broja klastera. FAT12 se koristi uglavnom za flopi diskove (do 4 KB), FAT16 za male diskove, FAT32 za FLASH drajvove veliki kapacitet(do 32 GB).

Razmotrite strukturu sistem podataka koristeći FAT32 kao primjer.

FAT32 struktura datoteke

Eksterni memorijski uređaji u sistemu FAT32 nemaju bajt, već blok adresiranje. Informacije se upisuju na vanjski memorijski uređaj u blokovima ili sektorima.

Sektor je najmanja adresabilna jedinica za skladištenje informacija na eksternim uređajima za skladištenje. Tipično, veličina sektora je fiksna na 512 bajtova. Da bi se povećao adresni prostor eksternih memorijskih uređaja, sektori se kombinuju u grupe koje se nazivaju klasteri.

Klaster je unija više sektora, koja se može smatrati nezavisnom jedinicom sa određenim svojstvima. Glavno svojstvo klastera je njegova veličina, mjerena brojem sektora ili brojem bajtova.

FAT32 sistem datoteka ima sljedeću strukturu.

Klasteri koji se koriste za snimanje fajlova su numerisani počevši od 2. U pravilu, klaster #2 koristi osnovni direktorijum, a počevši od klastera #3, pohranjuje se niz podataka. Sektori koji se koriste za pohranjivanje informacija predstavljenih iznad korijenskog direktorija nisu grupirani.
Minimalna veličina datoteke na disku je 1 klaster.

Sektor za pokretanje počinje sa sljedećim informacijama:

  • EB 58 90 - bezuslovna grana i potpis;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 - broj bajtova u sektoru (obično 512);
  • 1 bajt - broj sektora u klasteru;
  • 2 bajta - broj rezervnih sektora.

Osim toga, sektor za pokretanje sadrži sljedeće važne informacije:

  • 0x10 (1 bajt) - broj FAT tabela (obično 2);
  • 0x20 (4 bajta) - broj sektora na disku;
  • 0x2S (4 bajta) - broj klastera korijenskog direktorija;
  • 0x47 (11 bajtova) - oznaka volumena;
  • 0x1FE (2 bajta) - potpis boot sektor(55 AA).

Informacijski sektor fajl sistema sadrži:

  • 0x00 (4 bajta) - potpis (52 52 61 41);
  • 0x1E4 (4 bajta) - potpis (72 72 41 61);
  • 0x1E8 (4 bajta) - broj slobodnih klastera, -1 ako nije poznato;
  • 0x1EC (4 bajta) - broj posljednjeg snimljenog klastera;
  • 0x1FE (2 bajta) - potpis (55 AA).

FAT sadrži informacije o stanju svakog klastera na disku. Donja 2 bajta FAT skladišta F8 FF FF 0F FF FF FF FF (što odgovara stanju klastera 0 i 1, koji su fizički odsutni). Nadalje, stanje svakog klastera sadrži broj klastera u kojem se nastavlja trenutni fajl ili sljedeće informacije:

  • 00 00 00 00 - klaster je slobodan;
  • FF FF FF 0F - kraj trenutnog fajla.
  • 8 bajtova - naziv datoteke;
  • 3 bajta - ekstenzija datoteke;

Korijenski direktorij sadrži skup 32-bitnih zapisa informacija za svaku datoteku, koji sadrži sljedeće informacije:

U slučaju rada sa duga imena datoteke (uključujući ruska imena), naziv datoteke je kodiran u UTF-16 sistemu kodiranja. U ovom slučaju, 2 bajta se dodjeljuju za kodiranje svakog znaka. U ovom slučaju, naziv datoteke je napisan u obliku sljedeće strukture:

  • 1 bajt sekvence;
  • 10 bajtova sadrži najmanjih 5 znakova imena datoteke;
  • 1 bajt atribut;
  • 1 bajt rezerviran;
  • 1 bajt - ček suma DOS ime;
  • 12 bajtova sadrži 3 najmanje značajna znaka imena datoteke;
  • 2 bajta - broj prvog klastera;
  • drugi znakovi dugog imena.

Rad sa fajlovima u C jeziku

Za programera otvori datoteku je predstavljen kao niz podataka koji se čitaju ili pišu. Kada se datoteka otvori, ona je povezana sa I/O tok... Izlazne informacije se upisuju u tok, ulazne informacije se čitaju iz toka.

Kada se tok otvori za I/O, on se povezuje sa standardnom strukturom tipa FILE, koja je definirana u stdio.h. Struktura FILE sadrži potrebne informacije o fajlu.

Datoteka se otvara pomoću funkcije fopen (), koja vraća pokazivač na FILE strukturu, koja se može koristiti za naredne operacije s datotekom.

FILE * fopen (ime, tip);


ime - naziv datoteke za otvaranje (uključujući putanju),
type je pokazivač na niz znakova koji određuju kako pristupiti datoteci:
  • "r" - otvori datoteku za čitanje (datoteka mora postojati);
  • "w" - otvoren prazan fajl za snimanje; ako datoteka postoji, njen sadržaj se gubi;
  • "a" - otvorite datoteku za pisanje do kraja (za dodavanje); datoteka se kreira ako ne postoji;
  • "r +" - otvara fajl za čitanje i pisanje (datoteka mora postojati);
  • "w +" - otvara praznu datoteku za čitanje i pisanje; ako datoteka postoji, njen sadržaj se gubi;
  • "a +" - otvorite datoteku za čitanje i dodavanje, ako datoteka ne postoji, onda je kreirana.

Povratna vrijednost je pokazivač na otvoreni tok. Ako dođe do greške, vraća se NULL.

Funkcija fclose () zatvara tok ili tokove povezane s datotekama otvorenim pomoću fopen (). Tok za zatvaranje određen je argumentom funkcije fclose ().

Vraćena vrijednost: vrijednost 0, ako je stream uspješno zatvoren; konstantan EOF ako je došlo do greške.

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

#include
int main () (
FILE * fp;
char name = "my.txt";
if ((fp = fopen (ime, "r")) == NULL)
{
printf ( "Nije moguće otvoriti fajl");
getchar ();
return 0;
}
// uspješno otvorimo datoteku
... // potrebne radnje na podacima
fclose (fp);
getchar ();
return 0;
}

Čitanje znaka iz datoteke:

char fgetc (tok);


Argument funkcije je pokazivač na tok tipa FILE. Funkcija vraća kod pročitanog znaka. Ako se dostigne kraj datoteke ili dođe do greške, vraća se konstanta EOF.

Upisivanje karaktera u datoteku:

fputc (znak, tok);

Argumenti funkcije su znak i pokazivač na tok tipa FILE. Funkcija vraća kod pročitanog znaka.

Funkcije Fscanf () i fprintf () su slične scanf funkcije() i printf (), ali rade sa datotekama podataka i imaju prvi argument, pokazivač datoteke.

fscanf (stream, "Input Format", argumenti);

Zabilježite informacije u tekstualni fajl već smo naučili. - Ako niste naučili, pogledajte zadnji članak. Detaljno govori i opisuje

Ali šta ako datoteka već postoji i moramo iz nje pročitati informacije za obradu? Na sreću, i ovo je prilično jednostavno. Da vas podsjetim da postoji nekoliko opcija za implementaciju ovog zadatka, opisao sam samo jednu od njih. Opisan je onaj koji se meni lično iz nekog razloga čini najlakšim za percepciju.

#include

int main ()
{
char s1 //Varijabla će pročitati string
ifstream u (“C: \\\ FromC \\ myfile.txt”); //Otvaranje datoteke za čitanje informacija
u >> s1; //pročitaj red
u .close () // Zatvorite fajl

cout<Prikaz vrijednosti s1 na ekranu
return 0;
}

Ovo je najjednostavniji program za čitanje prvog reda iz tekstualne datoteke koja se nalazi duž putanje
C: \\\ FromC \\ myfile.txt -
Pošto je ovo nastavak prošlog članka, odlučio sam da koristim fajl koji smo tamo napravili. Vjerovatno ne bi trebalo biti nikakvih poteškoća sa ovim.
Ali vratimo se kodu. Prvo otvaramo datoteku da pročitamo informacije iz nje, za to koristimo naredbu ifstream, u zagradama označavamo ili ime datoteke, ili putanju do datoteke, kao što sam ja uradio. (“C: \\\ FromC \\ myfile.txt”);
Kada smo otvorili datoteku da pročitamo nešto iz nje, deklarirali smo jednu varijablu kao char -
char s1
Sada samo treba da dodelimo vrednost niza iz datoteke promenljivoj. Radimo ovo kao tim in
Obratite pažnju na ugaone zagrade u >>
Zapravo, kao što se vidi iz komentara na programski kod, da bi varijabla dodijelila pročitanu vrijednost, moramo je napisati nakon u >>
u >> s1;

Bez posebnog izazovan zadatak izgleda da to nije slučaj, pogotovo ako ste već savršeno savladali i naučili kako koristiti materijal iz prethodnog članka - sve je apsolutno isto, samo 2 naredbe su različite

Kreiranje datoteke i pisanje informacija u nju C++

ofstream van ( Ime dokumenta );
van<< (Written string);
van.close ();
=============================

Čitanje teksta iz datoteke i prikazivanje teksta na ekranu u C ++

ifstream in (Ime dokumenta );
in>> (Pročitali smo red);
in.close ();(Zatvorite fajl)
============================
Pisaćemo jednostavan program koji će pročitati unos teksta sa tastature i zapisati ga u datoteku:

#include
#include

int main ()
{
\\ 3 buduće linije
clrscsr (); //Čišćenje ekrana

cout<<“Wwedi pervuu stroku” ; cin >> a; endl;
cout<<“Wwedi wtoruu stroku” ; cin >> b; endl;
cout<<“Wwedi tretuu stroku” ; cin >> c; endl;
clrscr (); //

/ * Počnimo raditi s fajlom * /
outstream out (“C: \\\ FromC \\ myfile.txt”); //Otvaranje datoteke za pisanje
van<Zapisujemo prvi red
van<Zapisujemo drugi red
van<Zapisujemo treći red
out .close (); // Zatvorite fajl

// Postavi varijable na nulu

za (int i = 0; i<=255 ;i ++)
(a = * “”; b = * “”; c = * “”;)


ifstream u (“C: \\\ FromC \\ myfile.txt”);
u >> a >> b >> c; //Svaki novi red čitamo u novu varijablu
u .close (); // Zatvorite fajl

/* */

za (i = 0; a! = * “”; i ++)
{
if (i> sizeof (a)) break;
cout<

}
cout<<“\n” ; \\

/* */


{
if (i> sizeof (b)) break;
cout<
}
cout<<“\n” ; \\ Pomerite kursor u novi red

/* */

za (i = 0; s! = * “”; i ++)
{
if (i> sizeof (c)) break;
cout<<с ;
}

return 0;
}
===================

U gornjim primjerima postoji jedan takav OGROMNO nedostatak. Ako pokušamo da unesemo red koji sadrži razmake, onda program neće raditi kako nam je potrebno. Vjerovatno sam ne samo ja, već i mnogi drugi ljudi naišli na ovu grešku. Stoga ostavljam pogrešno dati kod kako biste mogli vidjeti na šta možete naići.

Kako kod kuće nema knjiga, ponovo sam počeo da pretražujem internet i naišao na gomilu raznoraznih zeznutih gluposti. Ipak, nekako sam pronašao rješenje za svoj problem.
Pomoglo mi je što sam to pročitao cout podržava njegove metode. A na internetu svi savjeti idu za korištenje funkcije getline Srećom, vrlo brzo sam pronašao kako da koristim ovu funkciju i onda je koristio u kodu.
Općenito, vrijedno je spomenuti i opisati ovu funkciju, ali do sada je nisam baš razumio, samo razumijem da je treba koristiti i razumjeti kako, pa dajem ispravniji primjer našeg razvijenog programa:

#include
#include

int main ()
{
char a, b, c; \\ 3 buduće linije
clrscsr (); //Čišćenje ekrana

/ * Unesite vrijednosti za varijable * /

cout<<“Wwedi pervuu stroku” ; cin.getline (a, sizeof (a)); endl;
cout<<“Wwedi wtoruu stroku” ; cin.getline (a, sizeof (b)); endl;
cout<<“Wwedi tretuu stroku” ; cin.getline (a, sizeof (c)); endl;
clrscr (); //Nakon unosa vrijednosti, obrisan ekran

/ * Počnimo raditi s fajlom * /
outstream out (“C: \\\ FromC \\ myfile.txt”); // Otvaranje datoteke za pisanje
van<
Zapisujemo prvi red
van<Zapisujemo drugi red
van<Zapisujemo treći red
out .close (); // Zatvorite fajl

// Postavi varijable na nulu

za (int i = 0; i<=255 ;i ++)
(a = * “”; b = * “”; c = * “”;)

/ * Nastavljamo rad sa fajlom * /

ako stream u (“C: \\\ FromC \\ myfile.txt”);
in.getline (a, sizeof (a));// a
in.getline (b, sizeof (b));// Čitamo liniju u varijablu b
in.getline (c, sizeof (c)); // Čitamo liniju u varijablu c
u .close (); // Zatvorite fajl

/* Čitamo prvi red znak po znak i prikazujemo ga na ekranu */

za (i = 0; a! = * “”; i ++)
{
if (i> sizeof (a)) break;
cout<

}
cout<<“\n” ; \\ Pomerite kursor u novi red

/* Čitamo drugi red znak po znak i prikazujemo ga na ekranu */

za (i = 0; b! = * “”; i ++)
{
if (i> sizeof (b)) break;
cout<
}
cout<<“\n” ; \\ Pomerite kursor u novi red

/* Čitamo treći red znak po znak i prikazujemo ga na ekranu */

za (i = 0; s! = * “”; i ++)
{
if (i> sizeof (c)) break;
cout<<с[i];
}

gettch (); \\Čeka se da se pritisne tipka Enter
return 0;
}
===================

U ovom materijalu analiziran je primjer čitanja informacija karakter po lik. Pošto nisam opisao kako se radi sa varijablama poput char, tada početnici mogu doživjeti neke neugodnosti u percepciji koda. Samo nisam znao koji je tip char ima neke posebnosti i mislim da je sve jednostavnije. Stoga, neke nerazumljive tačke gornjeg programa možete pročitati u sljedećem članku. rad sa char v C++ za početnike

Za ostalo, dati primjer kako čitati redove iz tekstualne datoteke u C ++ bi trebao biti dostupan i sasvim razumljiv. Ovo sada nije optimalna opcija implementacije i propustio sam neke važne tačke, ali pošto počinjemo da učimo jezik C++, ovo je za sada sasvim dovoljno. Kasnije ću verovatno doći do tačke u kojoj sam propustio, ali sada treba da shvatim samo ono najvažnije.

Ako smo zajedno sa vama razumeli ovaj materijal, to znači da smo napravili mali korak ka našoj profesionalnosti.

Bilješka:
break;- Ovo je komanda koja izlazi iz petlje. Imamo ako brojač ciklusa za postaje veća od deklarirane veličine varijable ugljen, onda nasilno izlazimo iz petlje
!= – ovo je naš uslov. Ovaj uslov je označen nejednakošću
ako (a! = b)- Čita kao da a nije jednako b

endl; - Ovo pomera kursor na novu liniju unutar konzole (koliko sam razumeo)
Ova komanda je slična "\ N"

Većina kompjuterskih programa radi sa datotekama, pa je stoga potrebno kreirati, brisati, pisati, čitati, otvarati datoteke. Šta je fajl? Datoteka je imenovani skup bajtova koji se može pohraniti na neki uređaj za pohranu. Pa, sada je jasno da se datoteka podrazumijeva kao određeni niz bajtova, koji ima svoje, jedinstveno ime, na primjer .txt fajl. Datoteke sa istim imenima ne mogu biti u jednom direktoriju. Ime datoteke znači ne samo njeno ime, već i ekstenziju, na primjer: file.txt i file.dat različite datoteke, iako imaju isti naziv. Postoji koncept kao što je puno ime datoteka - ovo je puna adresa direktorija datoteka s imenom datoteke, na primjer: D: \ docs \ file.txt. Važno je razumjeti ove osnovne koncepte, inače će biti teško raditi s datotekama.

Da biste radili sa fajlovima, potrebno je da povežete datoteku zaglavlja . V definirano je nekoliko klasa i uključene su datoteke zaglavlja unos datoteke i izlaz datoteke.

File I/O je sličan standardnom I/O, jedina razlika je u tome što se I/O ne vrši na ekranu, već na fajlu. Ako se I/O na standardne uređaje izvodi pomoću cin i cout objekata, onda je za organizaciju U/I fajla dovoljno kreirati vlastite objekte koji se mogu koristiti slično kao i cin i cout operatori.

Na primjer, trebate kreirati tekstualnu datoteku i u nju napisati red Rad s datotekama u C ++. Da biste to učinili, potrebno je izvršiti sljedeće korake:

  1. kreirati objekat klase ofstream ;
  2. povežite objekt klase sa datotekom u koju će se pisati;
  3. upisati liniju u datoteku;
  4. zatvorite fajl.

Zašto je potrebno kreirati objekat klase ofstream, a ne ifstream klase? Budući da trebate pisati u datoteku, i ako trebate čitati podatke iz datoteke, kreirat će se objekt klase ifstream.

// kreiranje objekta za pisanje u datoteku ofstream / * ime objekta * /; // objekt klase ofstream

Nazovimo objekat - fout Evo šta dobijate:

Ofstream fout;

Zašto nam je potreban objekat? Objekt je potreban da bi mogao pisati u datoteku. Objekt je već kreiran, ali nije povezan s datotekom u koju želite upisati string.

Fout.open ("cppstudio.txt"); // povezuje objekat sa fajlom

Operacijom tačke dobijamo pristup metodi klase open (), u čijim zagradama navodimo ime datoteke. Navedena datoteka će biti kreirana u trenutnom direktoriju s programom. Ako datoteka sa ovim imenom postoji, postojeća datoteka će biti prepisana novom. Dakle, datoteka je otvorena, ostaje da upišete potrebnu liniju u nju. Ovo se radi ovako:

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

Korištenjem stream operacije u sprezi sa fout objektom, File Worker u C ++ red se upisuje u datoteku. Pošto više nije potrebno mijenjati sadržaj datoteke, on se mora zatvoriti, odnosno objekt mora biti odvojen od datoteke.

Fout.close (); // zatvorite datoteku

Rezultat - kreiran je fajl sa linijom Rad sa datotekama u C ++.

Koraci 1 i 2 se mogu kombinovati, odnosno kreirati objekat u jednom redu i povezati ga sa datotekom. Ovo se radi ovako:

Ofstream fout ("cppstudio.txt"); // kreiramo objekat klase ofstream i povezujemo ga sa datotekom cppstudio.txt

Hajde da kombinujemo sav kod i dobijemo sledeći program.

// file.cpp: definira ulaznu točku za aplikaciju konzole. #include "stdafx.h" #include korištenje imenskog prostora std; int main (int argc, char * argv) (ofstream fout ("cppstudio.txt"); // kreiraj objekat klase ofstream za snimanje i poveži ga sa datotekom cppstudio.txt fout<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

Ostaje provjeriti ispravnost programa, a za to otvaramo datoteku cppstudio.txt i pogledamo njegov sadržaj, trebalo bi da bude - Rad sa fajlovima u C++.

  1. kreirajte objekat klase ifstream i povežite ga sa datotekom iz koje će se čitati;
  2. pročitajte datoteku;
  3. zatvorite fajl.
// file_read.cpp: definira ulaznu točku za aplikaciju konzole. #include "stdafx.h" #include #include korištenje imenskog prostora std; int main (int argc, char * argv) (setlocale (LC_ALL, "rus"); // ispravan prikaz ćiriličnog pisma char buff; // bafer za međuskladištenje teksta pročitanog iz datoteke ifstream fin ("cppstudio.txt "); // otvorio datoteku za čitanje fin >><< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку system("pause"); return 0; }

Program pokazuje dva načina čitanja iz datoteke, prvi koristi operaciju prijenosa u stream, drugi koristi funkciju getline () ... U prvom slučaju čita se samo prva riječ, au drugom se čita niz dužine 50 znakova. Ali pošto je u datoteci ostalo manje od 50 znakova, znakovi se čitaju, uključujući, do posljednjeg. Imajte na umu da čitanje po drugi put (red 17) se nastavlja, nakon prve riječi, a ne od početka, pošto je prva riječ pročitanared 14... Rezultat programa je prikazan na slici 1.

Rad sa datotekama u C++ Pritisnite bilo koji taster da nastavite. ... ...

Slika 1 - Rad sa datotekama u C++

Program je radio ispravno, ali to nije uvijek slučaj, čak i ako je sve u redu sa kodom. Na primjer, ime nepostojeće datoteke je proslijeđeno programu ili je napravljena greška u imenu. Šta onda? U ovom slučaju, ništa se neće dogoditi. Fajl neće biti pronađen, što znači da ga nije moguće pročitati. Stoga će kompajler zanemariti redove u kojima se pristupa datoteci. Kao rezultat toga, program će se ispravno zatvoriti, ali se ništa neće prikazati na ekranu. Čini se da je to sasvim normalna reakcija na takvu situaciju. Ali običan korisnik neće razumjeti u čemu je stvar i zašto se linija iz datoteke nije pojavila na ekranu. Dakle, da bi sve bilo vrlo jasno, C ++ pruža takvu funkciju - is_open (), koja vraća cjelobrojne vrijednosti: 1 - ako je datoteka uspješno otvorena, 0 - ako datoteka nije otvorena. Izmenimo program otvaranjem fajla, tako da ako fajl nije otvoren, da se prikaže odgovarajuća poruka.

// file_read.cpp: definira ulaznu točku za aplikaciju konzole. #include "stdafx.h" #include #include korištenje imenskog prostora std; int main (int argc, char * argv) (setlocale (LC_ALL, "rus"); // ispravan prikaz ćiriličnog pisma char buff; // bafer za međuskladištenje teksta pročitanog iz datoteke ifstream fin ("cppstudio.doc "); // ( UKLJUČENO NEISPRAVNO IME DATOTEKE) if (! Fin.is_open ()) // ako datoteka nije otvorena cout<< "Файл не может быть открыт!\n"; // сообщить об этом else { fin >> buff; // čitamo prvu riječ iz datoteke cout<< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку } system("pause"); return 0; }

Rezultat programa je prikazan na slici 2.

Fajl se ne može otvoriti! Pritisnite bilo koji taster da nastavite. ... ...

Slika 2 – Rad sa datotekama u C++

Kao što možete vidjeti na slici 2, program je prijavio nemogućnost otvaranja datoteke. Stoga, ako program radi s datotekama, preporučuje se korištenje ove funkcije, is_open (), čak i ako ste sigurni da datoteka postoji.

Načini otvaranja datoteka

Načini otvaranja datoteka postavljaju način na koji se datoteke koriste. Za postavljanje režima u klasi ios_base, obezbeđene su konstante koje određuju način otvaranja datoteka (pogledajte tabelu 1).

Načini otvaranja datoteke mogu se postaviti direktno prilikom kreiranja objekta ili prilikom pozivanja funkcije open (). .

Ofstream fout ("cppstudio.txt", ios_base :: app); // otvorite datoteku da dodate informacije na kraj datoteke fout.open ("cppstudio.txt", ios_base :: app); // otvorite datoteku da dodate informacije na kraj datoteke

Načini otvaranja datoteka mogu se kombinirati korištenjem bitne logičke operacije ili| , na primjer: ios_base :: out | ios_base :: trunc - otvorite datoteku za pisanje, nakon što je obrišete.

Objekti klase ofstream, kada su povezani sa fajlovima, podrazumevano sadrže modove za otvaranje fajlova ios_base :: out | ios_base :: trunc . Odnosno, datoteka će biti kreirana ako ne postoji. Ako datoteka postoji, njen sadržaj će biti obrisan, a sam fajl će biti spreman za pisanje. Objekti ifstream klase koji se povezuju sa datotekom imaju zadani način otvaranja datoteke ios_base :: in - datoteka je otvorena samo za čitanje. Način otvaranja fajla se također naziva zastavica, radi čitljivosti u budućnosti ćemo koristiti upravo ovaj termin. Nisu sve zastavice navedene u Tabeli 1, ali ove bi trebale biti dovoljne za početak.

Imajte na umu da su ate i app zastavice vrlo slične u opisu, obje pomiču pokazivač na kraj datoteke, ali zastavica aplikacije dozvoljava pisanje samo do kraja datoteke, a ate zastavica jednostavno pomiče zastavicu na kraj datoteke i ne ograničava lokacije za pisanje.

Hajde da razvijemo program koji će, koristeći operaciju sizeof (), izračunati karakteristike osnovnih tipova podataka u C ++ i zapisati ih u datoteku. specifikacije:

  1. broj bajtova dodijeljenih za tip podataka
  2. maksimalna vrijednost koju određeni tip podataka može pohraniti.

Pisanje u fajl treba da se obavi u sledećem formatu:

/ * Tip podataka bajt max vrijednost bool = 1 255,00 char = 1 255,00 short int = 2 32.767,00 unsigned short int = 2 65.535,00 int = 4 2147483647,00 unsigned int = 4 4294967295,00 long int = 4 2147483647,00 unsigned long int = 4 4294967295,00 float = 4 2147483647,00 dugi plutajući = 8 9223372036854775800.00 dupli = 8 9223372036854775800.00 * /

Takav program je već razvijen ranije u ovom odjeljku, ali tamo su sve informacije o tipovima podataka bile izlazne na standardni izlazni uređaj, a mi moramo prepraviti program tako da se informacije upisuju u datoteku. Da biste to učinili, morate otvoriti datoteku u načinu snimanja, uz prethodno skraćenje trenutnih informacija o datoteci ( red 14). Nakon što je datoteka kreirana i uspješno otvorena (redovi 16 - 20), umjesto naredbe cout, u red 22 koristite fout objekat. stoga se, umjesto ekrana, informacije o tipu podataka upisuju u datoteku.

// write_file.cpp: definira ulaznu točku za aplikaciju konzole. #include "stdafx.h" #include #include // rad s datotekama #include // U/I manipulatori koji koriste prostor imena std; int main (int argc, char * argv) (setlocale (LC_ALL, "rus"); // veže objekat na datoteku i otvori datoteku u načinu pisanja, nakon što iz nje uklonimo sve podatke iz toka fout ("data_types.txt ", ios_base :: out | ios_base :: trunc); if (! fout.is_open ()) // ako datoteka nije otvorena (cout<< "Файл не может быть открыт или создан\n"; // напечатать соответствующее сообщение return 1; // выполнить выход из программы } fout << " data type " << "byte" << " " << " max value "<< endl // zaglavlja stupaca <<"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; }

Nemoguće je ne primijetiti da su promjene u programu minimalne, a sve zbog činjenice da se standardni ulaz/izlaz i ulaz/izlaz datoteke koriste na potpuno isti način. Na kraju programa, ured 45eksplicitno smo zatvorili datoteku, iako nije potrebno, smatra se dobrom programskom praksom. Vrijedi napomenuti da su sve funkcije i manipulatori koji se koriste za formatiranje standardnog I/O relevantni i za fajl I/O. Dakle, nije bilo grešaka kod operatera cout je zamijenjen objektom fout.

Rad sa tekstualnim datotekama u C++.

Postoje dvije glavne vrste datoteka: tekstualni i binarni. Datoteke omogućavaju korisniku da čita velike količine podataka direktno sa diska bez da ih ukuca sa tastature.

    Tekst datoteke koje se sastoje od bilo kojeg karaktera se pozivaju. Oni su organizirani u redove, od kojih se svaki završava znakom na kraju reda. Kraj samog fajla je označen simbolom "kraj datoteke". Prilikom pisanja informacija u tekstualnu datoteku, koja se može vidjeti pomoću bilo kojeg uređivača teksta, svi podaci se pretvaraju u tip znakova i pohranjuju u obliku znakova.

    V binarni datoteke, informacije se čitaju i zapisuju u obliku blokova određene veličine, u koje se mogu pohraniti podaci bilo koje vrste i strukture.

Za rad sa fajlovima, specijal tipovi podataka pozvao potoci... Flow ifstream služi za rad sa fajlovima u režimu čitanja, i ofstream u režimu snimanja. Za rad sa datotekama u načinu pisanja i čitanja, koristite stream fstream.

U C ++ programima, kada radite s tekstualnim datotekama, morate uključiti biblioteke iostream i fstream.

Da bi zapiši podatke u tekstualnu datoteku, morate:

    opisati varijablu tipa toka.

    izlazne informacije u datoteku.

    obavezno zatvorite fajl.

Za očitavanja podatke iz tekstualne datoteke, morate:

    opisati varijablu tipa ifstream.

    otvorite datoteku koristeći funkciju otvaranja.

    zatvorite fajl.

Snimanje informacije u tekstualnoj datoteci

    Kao što je ranije spomenuto, da biste počeli raditi s tekstualnom datotekom, morate deklarirati varijablu tipa ofstream. Na primjer, ovako:

    Varijabla F će biti kreirana za upisivanje informacija u datoteku.

    Sljedeći korak je otvaranje datoteke za pisanje. Općenito, operator otvaranja toka će izgledati ovako:

F.open ("file", mod);

Ovdje je F varijabla, opisana kao offstream,

fajl - puni naziv fajla na disku,

mode - način rada sa datotekom koja se otvara.

Imajte na umu da morate koristiti dvostruku kosu crtu kada navodite puno ime datoteke. Na primjer, puno ime datoteke noobs.txt koja se nalazi u folderu igre na D: disku bi trebalo biti napisano ovako:

D: \\ igra \\ noobs.txt.

Datoteka se može otvoriti na jedan od sljedećih načina:

ios :: in - otvorite datoteku u načinu čitanja podataka, ovaj način je zadani način za ifstream streamove;

ios :: out - otvara fajl u režimu snimanja podataka (informacije o postojećoj datoteci su uništene), ovaj režim je podrazumevani režim za offstream streamove;

ios :: app - otvorite datoteku u načinu upisivanja podataka do kraja datoteke;

ios :: ate - prelazak na kraj već otvorene datoteke;

ios :: trunc - obrišite datoteku, isto se dešava u ios :: out modu;

ios :: nocreate - ne otvaraj datoteku ako ne postoji;

ios :: noreplace - ne otvaraj postojeći fajl.

Parametar moda može biti odsutan, u ovom slučaju datoteka se otvara u zadanom načinu za ovaj stream.

Nakon uspješnog otvaranja datoteke (u bilo kojem načinu rada), varijabla F će pohraniti true, u suprotnom false. Ovo će provjeriti ispravnost operacije otvaranja datoteke.

Možete otvoriti datoteku (uzmite datoteku D: \\ game \\ noobs.txt kao primjer) u načinu snimanja na jedan od sljedećih načina:

// prvo način

offstream F;

F.open ("D: \\ igra \\ noobs.txt", ios :: out);

// drugi način, ios :: out mod je default

// za protokofstream

offstream F;

// treći način kombinuje opis varijable i tok tipa

// i otvorimo datoteku u jednoj izjavi

ofstream F ("D: \\ game \\ noobs.txt", ios :: out);

Nakon otvaranja datoteke u načinu pisanja, kreirat će se prazna datoteka u koju će biti moguće upisati informacije.

Ako želite da otvorite postojeću datoteku u režimu pre pisanja, koristite vrednost aplikacije ios :: kao režim.

Nakon otvaranja datoteke u načinu pisanja, možete u nju pisati na isti način kao i na ekran, samo umjesto standardnog izlaznog uređajacoutmorate navesti ime otvorene datoteke.

Na primjer, za pisanje varijable a u tok F, izlazni operator će izgledati ovako:

Za sekvencijalni izlaz u tok G varijabli b, c, d, izlazni operator će postati:

G<

Tok se zatvara pomoću operatora:

PRIMJER:

Kreirajte tekstualni fajl D: \\ game \\ noobs.txt i u njega upišite n realnih brojeva.

#include "stdafx.h"

#include

#include

#include

korištenje imenskog prostora std;

int main ()

setlocale (LC_ALL, "RUS");

int i, n;

duplo a;

// opisuje tok za pisanje podataka u datoteku

ofstream f;

// otvorite datoteku u načinu pisanja,

//modeios:: vaninstaliran prema zadanim postavkama

f.open ("D: \\ igra \\ noobs.txt", ios :: out);

// unesite broj realnih brojeva

cout<<" n="; cin>> n;

// petlja za unos realnih brojeva

// i zapisati ih u datoteku

za (i = 0; i

cout<<"a=";

// unesite broj

cin >> a;

f<

// zatvori tok

f.close ();

sistem ("pauza");

return 0;

_______________________________________________________________

Da biste pročitali informacije iz tekstualne datoteke, morate deklarirati varijablu tog tipa ifstream... Nakon toga morate otvoriti datoteku za čitanje pomoću operatora otvoren... Ako se varijabla zove F, tada će prva dva operatora biti ovako:

F.open ("D: \\ igra \\ noobs.txt", ios :: in);

Nakon otvaranja datoteke u načinu čitanja, možete čitati informacije iz nje na isti način kao s tastature, samo umjestocinnavedite ime toka iz kojeg će se podaci čitati.

Na primjer, za čitanje iz toka F u varijablu a, input izraz bi izgledao ovako:

Dva broja u uređivaču teksta smatraju se odvojenima ako između njih postoji barem jedan znak: razmak, tabela, znak na kraju reda. Dobro je ako programer unaprijed zna koliko i koje vrijednosti je pohranjeno u tekstualnoj datoteci. Međutim, tip vrijednosti pohranjenih u datoteci često je jednostavno poznat, a njihov broj može varirati. Prilikom rješavanja ovog problema potrebno je čitati vrijednosti iz datoteke jednu po jednu, a prije svakog čitanja provjeriti da li je došlo do kraja datoteke. Za to postoji funkcija F. eof().

Ovdje je F ime toka Funkcija vraća logičku vrijednost: true ili false, ovisno o tome da li je dostignut kraj datoteke. Stoga se petlja za čitanje sadržaja cijele datoteke može napisati ovako:

// urediti za čitanje vrijednosti iz datoteke, izvršiti

// petlja će se prekinuti kada dođemo do kraja datoteke,

// u ovom slučaju F.eof () će vratiti true

dok (! F.eof ())

PRIMJER:

Realni brojevi se pohranjuju u tekstualnu datoteku D: \\ game \\ noobs.txt, prikažite ih na ekranu i izračunajte njihov broj.

#include "stdafx.h"

#include

#include

#include

#include

korištenje imenskog prostora std;

int main ()

setlocale (LC_ALL, "RUS");

int n = 0;

float a;

fstream F;

// otvorite datoteku u načinu čitanja

F.open ("D: \\ igra \\ noobs.txt");

// ako je datoteka ispravno otvorena, onda

// petlja za čitanje vrijednosti iz datoteke; izvođenje ciklusa će biti prekinuto,

// kada dođemo do kraja datoteke, u ovom slučaju F.eof () će vratiti true.

dok (! F.eof ())

// čitanje sljedeće vrijednosti iz toka F u varijablu a

F >> a;

// prikazuje vrijednost varijable a na ekranu

cout<

// povećava broj pročitanih brojeva

// zatvori tok

F.close ();

// unos na ekran broj pročitanih brojeva

cout<<"n="<

// ako je datoteka pogrešno otvorena, onda izlaz

// poruke o nepostojanju takve datoteke

else cout<<" Файл не существует"<

sistem ("pauza");

return 0;

C ++. Rukovanje binarnim datotekama

Prilikom pisanja informacija u binarnu datoteku, znakovi i brojevi se zapisuju kao niz bajtova.

Da bi zapiši podatke u binarnu datoteku, potrebno je:

    opišite varijablu datoteke tipa FAIL * koristeći izraz FILE * ime datoteke;. Ovdje naziv datoteke je ime varijable gdje će se pohraniti pokazivač datoteke.

    zapisati informacije u datoteku koristeći fwrite funkciju

Da bi čitaj b podatke iz binarne datoteke, morate:

    opišite varijablu tipa FILE *

    otvorite datoteku sa fopen funkcijom

    zatvorite datoteku pomoću funkcije fclose

Osnovne funkcije potrebne za rad sa binarnim datotekama.

Za otkrića datoteka, funkcija fopen je namijenjena.

FILE * fopen (const * filename, const char * mod)

Ovdje filename je string koji pohranjuje puno ime datoteke za otvaranje, mode je niz koji definira način rada sa datotekom; moguće su sljedeće vrijednosti:

"Rb" - otvaranje binarne datoteke u načinu čitanja;

"Wb" - kreirati binarnu datoteku za pisanje; ako postoji, onda se njegov sadržaj briše;

"Ab" - kreirajte ili otvorite binarnu datoteku koju želite dodati na kraj datoteke;

"Rb +" - otvaranje postojeće binarne datoteke u načinu čitanja i pisanja;

"Wb +" - otvorite binarnu datoteku u načinu čitanja / pisanja, postojeća datoteka se briše;

"Ab +" - otvara se ili kreira binarna datoteka kako bi se ispravile postojeće informacije i dodale nove informacije na kraj datoteke.

Funkcija vraća NULL u varijablu datoteke f ako se datoteka ne otvori uspješno. Nakon otvaranja datoteke, njen 0-ti bajt je dostupan, pokazivač datoteke je 0, čija se vrijednost pomjera za broj bajtova koji se čitaju (upisuju) dok se čita ili upisuje. Trenutna vrijednost pokazivača datoteke je broj bajta, počevši od kojeg će se izvršiti operacija čitanja ili pisanja.

Za zatvaranje datoteku, funkcija fclose je namijenjena

int fclose (FILE * ime datoteke);

Vraća 0 nakon uspješnog zatvaranja datoteke i NULL u suprotnom.

Funkcija uklanjanja je za brisanje datoteke.

int remove (const char * ime datoteke);

Ova funkcija uklanja datoteku pod nazivom filenema s diska. Datoteka koju treba izbrisati mora biti zatvorena. Funkcija vraća različitu od nule ako se datoteka ne može izbrisati.

Za preimenovanje datoteke, funkcija preimenovanja je namijenjena:

int preimenuj (const char * oldfilename, const char * newfilename);

Prvi parametar je staro ime datoteke, drugi je novi. Vraća 0 po uspjehu.

Čitanje iz binarne datoteke se radi pomoću funkcije fread:

fread (void * ptr, veličina, n, FILE * ime datoteke);

Funkcija fread čita n elemenata veličine veličine iz naziva datoteke u niz ptr. Funkcija vraća broj pročitanih stavki. Nakon čitanja iz datoteke, njen pokazivač se pomjera za n * bajtova veličine.

Snimanje u binarnu datoteku se vrši pomoću funkcije fwrite:

fwrite (const void * ptr, veličina, n, FILE * ime datoteke);

Funkcija fwrite upisuje n elemenata veličine u ime datoteke iz ptr niza. Funkcija vraća broj upisanih elemenata. Nakon upisivanja informacija u datoteku, pokazivač se pomjera za n * bajtova veličine.

Za kontrola kraja datoteke postoji feof funkcija:

int feof (FILE * ime datoteke);

Vraća različitu od nule ako je dostignut kraj datoteke.

PRIMJER:

Kreirajte binarni fajl D: \\ game \\ noobs.dat i u njega upišite cijeli broj n i n realnih brojeva.

#include "stdafx.h"

#include

korištenje imenskog prostora std;

int main ()

setlocale (LC_ALL, "RUS");

int n, i;

duplo a;

// kreiramo binarnu datoteku u načinu pisanja

f = fopen ("D: \\ igra \\ noobs.dat", "wb");

// unos brojevin

cout<<"n="; cin>> n;

fwrite (& n, sizeof (int), 1, f);

// petlja za unos n realnih brojeva

za (i = 0; i

// unos sljedećeg realnog broja

cout<<"a=";

cin >> a;

// upisuje realni broj u binarnu datoteku

fwrite (& a, sizeof (dvostruko), 1, f);

// zatvori fajl

fclose (f);

sistem ("pauza");

return 0;

PRIMJER:

Prikaži sadržaj binarnog fajla D: \\ game \\ noobs.dat kreiranog u prethodnom zadatku

#include "stdafx.h"

#include

korištenje imenskog prostora std;

int main ()

setlocale (LC_ALL, "RUS");

int n, i;

duplo * a;

FILE * f; // opisuje varijablu datoteke

// otvara postojeću binarnu datoteku u načinu čitanja

// čitanje iz datoteke jedan cijeli broj u varijablu n

// prikazuje n na ekranu

cout<<"n="<

// dodjela memorije za niz od n brojeva

a = novi dupli [n];

// čitanje n realnih brojeva iz datoteke u niz a

// prikazuje niz na ekranu

za (i = 0; i

cout<

cout<

// zatvori fajl

fclose (f);

sistem ("pauza");

return 0;

Binarni fajl- sekvencijalna struktura podataka, nakon otvaranja datoteke, dostupan je prvi bajt pohranjen u njoj. Možete sekvencijalno pisati ili čitati podatke iz datoteke. Recimo da želite da izbrojite petnaesti broj, a zatim prvi. Uz sekvencijalni pristup, to se može učiniti na sljedeći način:

int n, i;

duplo a;

FILE * f;

f = fopen ("D: \\ igra \\ noobs.dat", "rb");

za (i = 0; i<15; i++)

fclose (f);

f = fopen ("D: \\ igra \\ noobs.dat", "rb");

fread (& a, sizeof (double), 1, f);

fclose (f);

Kao što vidite, čitanje brojeva iz datoteke na ovaj način, a zatim ponovno otvaranje datoteke nije najpogodniji način. Mnogo je zgodnije koristiti funkciju fseek za pomicanje pokazivača datoteke na dati bajt.

int fseek (FILE * ime datoteke, dugi int pomak, int porijeklo);

Funkcija postavlja pokazivač na trenutnu poziciju datoteke F prema vrijednosti početka i pomaka. Parametar pomaka jednak je broju bajtova za koji će pokazivač datoteke biti pomaknut od početka specificiranog parametrom porijekla. Parametar porijekla mora biti jedna od sljedećih vrijednosti pomaka kako je definirano u zaglavlju stdio.h:

SEEK_SET - od početka fajla;

SEEK_CUR - sa trenutne pozicije;

SEEK_END - sa kraja fajla.

Funkcija vraća nulu ako je operacija uspješna, različitu od nule ako dođe do greške prilikom izvršavanja pomaka

Funkcija fseek zapravo implementira direktan pristup bilo kojoj vrijednosti u datoteci. Vi samo trebate znati lokaciju (broj bajta) vrijednosti u datoteci. Pogledajmo upotrebu direktnog pristupa u binarnim datotekama koristeći primjer rješavanja sljedećeg problema.

PRIMJER

U prethodno generiranoj binarnoj datoteci D: \\ game \\ noobs.dat, zamijenite najveći i najmanji realni broj.

Algoritam za rješavanje problema sastoji se od sljedećih faza:

    čitanje pravih iz datoteke u niz a.

    potražite u nizu a maksimalne (max) i minimalne (min) vrijednosti i njihove brojeve (imax, imin).

    pomaknite pokazivač datoteke na maksimalnu vrijednost i upišite min.

    pomaknite pokazivač datoteke na minimalnu vrijednost i upišite max.

Ispod je tekst programa za rješavanje problema s komentarima.

#include "stdafx.h"

#include

korištenje imenskog prostora std;

int main ()

setlocale (LC_ALL, "RUS");

int n, i, imax, imin;

duplo * a, max, min;

FILE * f;

// otvaramo datoteku u načinu čitanja i pisanja

f = fopen ("D: \\ igra \\ noobs.dat", "rb +");

// čitanje iznosa iz datoteke u varijablu n

// realni brojevi u datoteci

fread (& n, sizeof (int), 1, f);

cout<<"n="<

// dodijeliti memoriju za pohranjivanje realnih brojeva,

// koji će biti pohranjen u nizu a

a = novi dupli [n];

// čitanje iz datoteke u niz i realne brojeve

fread (a, sizeof (dvostruko), n, f);

// pronalazimo maksimum i minimum elemenata

// u nizu a i njihovim indeksima

za (imax = imin = 0, max = min = a, i = 1; i

ako (a [i]> max)

max = a [i];

ako (a [i]

min = a [i];

// kreće se pokazivač To maksimum element

fseek (f, sizeof (int) + imax * sizeof (double), SEEK_SET);

// upisuje min umjesto maksimalnog elementa datoteke

fwrite (& min, sizeof (dvostruko), 1, f);

// kreće se pokazivač To minimalno element

fseek (f, sizeof (int) + imin * sizeof (double), SEEK_SET);

// piše max umjesto minimalnog elementa datoteke

fwrite (& max, sizeof (double), 1, f);

// zatvorite datoteku

fclose (f);

// slobodna memorija

obriši [ ] a;

sistem ("pauza");

Tagovi: Tekstualne datoteke, fopen, fclose, feof, setbuf, setvbuf, fflush, fgetc, fprintf, fscanf, fgets, baferirani tok, nebaferirani tok.

Rad sa tekstualnim fajlovima

Rad s tekstualnom datotekom sličan je radu s konzolom: koristeći formatirane ulazne funkcije, spremamo podatke u datoteku, koristeći formatirane izlazne funkcije, čitamo podatke iz datoteke. Mnogo je nijansi koje ćemo kasnije razmotriti. Glavne operacije koje treba obaviti su

  • 1. Otvorite datoteku tako da se možete obratiti na nju. Shodno tome, moguće je otvaranje za čitanje, pisanje, čitanje i pisanje, prepisivanje ili pisanje do kraja datoteke itd. Kada otvorite datoteku, može se pojaviti i gomila grešaka - datoteka možda ne postoji, možda je pogrešan tip datoteke, možda nemate dozvolu za rad sa datotekom itd. Sve ovo se mora uzeti u obzir.
  • 2. Direktan rad sa fajlom - pisanje i čitanje. Ovdje također treba imati na umu da ne radimo sa memorijom sa slučajnim pristupom, već sa baferovanim streamom, koji dodaje svoje specifičnosti.
  • 3. Zatvorite datoteku. Budući da je datoteka resurs izvan programa, ako nije zatvorena, nastavit će visiti u memoriji, moguće čak i nakon što se program zatvori (na primjer, neće biti moguće izbrisati otvorenu datoteku ili izvršiti izmjene, itd.). Osim toga, ponekad je potrebno ne zatvoriti, već "ponovno otvoriti" datoteku da bi se, na primjer, promijenio način pristupa.

Osim toga, postoji niz zadataka kada ne trebamo pristupiti sadržaju datoteke: preimenovati, premjestiti, kopirati itd. Nažalost, C standard ne daje opis funkcija za ove potrebe. Oni su, naravno, dostupni za svaku implementaciju kompajlera. Čitanje sadržaja direktorija (folder, direktorij) je također pristup datoteci, jer je sama mapa datoteka sa metainformacijama.

Ponekad je potrebno izvršiti neke pomoćne operacije: premjestiti se na željenu lokaciju u datoteci, zapamtiti trenutnu poziciju, odrediti dužinu datoteke itd.

Za rad sa fajlom potreban je objekat FILE. Ovaj objekat pohranjuje ID toka datoteke i informacije koje su vam potrebne da biste njime manipulirali, uključujući pokazivač na njegov bafer, indikator pozicije datoteke i indikatore statusa.

FILE objekat je sam po sebi struktura, ali njegovim poljima ne bi trebalo pristupati. Prijenosni program mora tretirati datoteku kao apstraktni objekt koji dozvoljava pristup toku datoteke.

Kreiranje i dodjela memorije za objekt tipa FILE vrši se pomoću fopen ili tmpfile funkcija (postoje i druge, ali ćemo se fokusirati samo na njih).

Funkcija fopen otvara datoteku. Potrebna su dva argumenta - string sa adresom datoteke i string sa načinom pristupa datoteci. Ime datoteke može biti apsolutno ili relativno. fopen vraća pokazivač na FILE objekat koji se može koristiti za dalji pristup datoteci.

FILE * fopen (const char * naziv datoteke, const char * mod);

Na primjer, otvorimo datoteku i napišemo u nju Hello World

#include #include #include void main () (// Pomoću varijable datoteke pristupit ćemo datoteci FILE * file; // Otvorite tekstualnu datoteku s dozvolama za pisanje file = fopen ("C: /c/test.txt", "w + t") ; // Upiši u datoteku fprintf (fajl, "Zdravo, svijet!"); // Zatvori datoteku fclose (fajl); getch ();)

Funkcija fopen sama dodjeljuje memoriju za objekt, čišćenje se vrši funkcijom fclose. Obavezno zatvoriti fajl, neće se sam zatvoriti.

Funkcija fopen može otvoriti datoteku u tekstualnom ili binarnom načinu. Zadana vrijednost je tekst. Način pristupa može biti sljedeći

Parametri pristupa fajlu.
Tip Opis
r Čitanje. Fajl mora postojati.
w Pisanje novog fajla. Ako datoteka sa istim imenom već postoji, njen sadržaj će biti izgubljen.
a Pisanje do kraja datoteke. Operacije pozicioniranja (fseek, fsetpos, frewind) se zanemaruju. Datoteka se kreira ako nije postojala.
r + Čitanje i ažuriranje. Možete i čitati i pisati. Fajl mora postojati.
w + Snimanje i ažuriranje. Nova datoteka je kreirana. Ako datoteka sa istim imenom već postoji, njen sadržaj će biti izgubljen. Možete i pisati i čitati.
a + Završite pisanje i ažuriranje. Operacije pozicioniranja su samo za čitanje; zanemaruju se za pisanje. Ako datoteka nije postojala, kreirat će se novi.

Ako trebate otvoriti datoteku u binarnom načinu, onda se slovo b dodaje na kraj reda, na primjer, "rb", "wb", "ab", ili, za mješoviti način, "ab +", “wb +”, “ab +”. Umjesto b, možete dodati slovo t, tada će se datoteka otvoriti u tekstualnom modu. Zavisi od implementacije. U novom C standardu (2011), slovo x znači da bi fopen funkcija trebala propasti ako datoteka već postoji. Hajde da dopunimo naš stari program: ponovo otvorimo fajl i smatramo da smo tamo napisali.

#include #include #include void main () (FILE * datoteka; char bafer; file = fopen ("C: /c/test.txt", "w"); fprintf (datoteka, "Hello, World!"); fclose (datoteka); datoteka = fopen ("C: /c/test.txt", "r"); fgets (bafer, 127, datoteka); printf ("% s", bafer); fclose (datoteka); getch ();)

Mogli ste koristiti fscanf umjesto fgets, ali zapamtite da može čitati samo red do prvog razmaka.
fscanf (fajl, "% 127s", bafer);

Također, umjesto otvaranja i zatvaranja datoteke, možete koristiti funkciju freopen, koja "ponovo otvara" datoteku s novim dozvolama.

#include #include #include void main () (FILE * datoteka; char bafer; file = fopen ("C: /c/test.txt", "w"); fprintf (datoteka, "Hello, World!"); freopen ("C: / c / test.txt "," r ", datoteka); fgets (bafer, 127, datoteka); printf ("% s ", bafer); fclose (datoteka); getch ();)

Funkcije fprintf i fscanf razlikuju se od printf i scanf samo po tome što kao svoj prvi argument uzimaju pokazivač na FILE na koji će ispisati ili iz kojeg će čitati podatke. Ovdje vrijedi odmah dodati da se funkcije printf i scanf mogu bez problema zamijeniti funkcijama fprintf i fscanf. U OS-u (razmatramo najčešće i adekvatnije operativne sisteme) postoje tri standardna toka: standardni izlazni stdout, standardni ulazni stdin i standardni izlaz greške stderr. Oni se automatski otvaraju prilikom pokretanja aplikacije i pridruženi su konzoli. Primjer

#include #include #include void main () (int a, b; fprintf (stdout, "Unesite dva broja \ n"); fscanf (stdin, "% d", & a); fscanf (stdin, "% d", & b); ako (b == 0) (fprintf (stderr, "Greška: podijeli sa nulom");) else (fprintf (stdout, "% .3f", (float) a / (float) b);) getch ();)

Greška pri otvaranju datoteke

Ako poziv fopen ne uspije, vratit će NULL. Greške u radu sa fajlovima su prilično česte, tako da svaki put kada otvorimo fajl, moramo da proverimo rezultat rada.

#include #include #include #define ERROR_OPEN_FILE -3 void main () (FILE * datoteka; char bafer; file = fopen ("C: /c/test.txt", "w"); if (file == NULL) (printf ("Greška pri otvaranju file "); getch (); izlaz (ERROR_OPEN_FILE);) fprintf (datoteka," Zdravo, svijet! "); freopen (" C: /c/test.txt "," r ", datoteka); if (datoteka = = NULL) (printf ("Greška pri otvaranju datoteke"); getch (); izlaz (ERROR_OPEN_FILE);) fgets (bafer, 127, datoteka); printf ("% s", bafer); fclose (datoteka); getch () ;)

Problem nastaje u slučaju kada se otvori nekoliko datoteka odjednom: ako se jedna od njih ne može otvoriti, onda se i ostale moraju zatvoriti.

FILE * inputFile, * outputFile; neoznačeno m, n; neoznačeno i, j; inputFile = fopen (INPUT_FILE, READ_ONLY); if (inputFile == NULL) (printf ("Greška pri otvaranju datoteke% s", INPUT_FILE); getch (); izlaz (3);) outputFile = fopen (OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) (printf ("Greška pri otvaranju datoteke% s", OUTPUT_FILE); getch (); if (inputFile! = NULL) (fclose (inputFile);) exit (4);) ...

U jednostavnim slučajevima, možete djelovati direktno, kao u prethodnom dijelu koda. U složenijim slučajevima koriste se metode koje zamjenjuju RAII iz C++: omoti ili karakteristike kompajlera (čišćenje u GCC-u) itd.

Baferovanje podataka

Kao što je ranije spomenuto, kada izbacimo podatke, oni se prvo stavljaju u bafer. Međuspremnik je obrisan

  • 1) Ako je puna
  • 2) Ako je tok zatvoren
  • 3) Ako eksplicitno naznačimo da je potrebno očistiti bafer (tu ima i izuzetaka :)).
  • 4) Također se briše ako je program uspješno završio. Istovremeno, svi fajlovi su zatvoreni. Ako postoji greška tokom izvođenja, to se možda neće dogoditi.

Možete prisilno isprazniti bafer pozivanjem funkcije fflush (File *). Pogledajmo dva primjera - sa i bez čišćenja.

#include #include #include void main () (FILE * datoteka; char c; file = fopen ("C: /c/test.txt", "w"); do (c = getch (); fprintf (datoteka, "% c", c ); fprintf (stdout, "% c", c); // fflush (datoteka);) while (c! = "q"); fclose (datoteka); getch ();)

Dekomentirajte flush poziv. Za vrijeme izvođenja otvorite tekstualnu datoteku i promatrajte ponašanje.

Možete sami dodijeliti bafer datoteke postavljanjem vlastite veličine. Ovo se radi pomoću funkcije

Void setbuf (FILE * stream, char * bafer);

koji uzima već otvorenu FILE i pokazivač na novi bafer. Veličina novog bafera ne smije biti manja od BUFSIZ (na primjer, na trenutnoj radnoj stanici, BUFSIZ je 512 bajtova). Ako prosledite NULL kao bafer, tok će postati nebaferovan. Također možete koristiti funkciju

Int setvbuf (FILE * stream, char * bafer, int mod, size_t veličina);

koji uzima bafer proizvoljne veličine. Mod može poprimiti sljedeće vrijednosti

  • _IOFBF- puno puferovanje. Podaci se upisuju u datoteku kada je puna. Prilikom čitanja, bafer se smatra punim kada je zatražena operacija unosa, a bafer je prazan.
  • _IOLBF- linearno puferovanje. Podaci se upisuju u datoteku kada je puna ili kada se naiđe na znak novog reda. Prilikom čitanja, bafer se popunjava do znaka novog reda kada se traži operacija unosa, a bafer je prazan.
  • _IONBF- nema puferovanja. U ovom slučaju, veličina i parametri međuspremnika se zanemaruju.
Ako je uspješna, funkcija vraća 0.

Primjer: postavimo vlastiti bafer i vidimo kako se čita iz datoteke. Neka datoteka bude kratka (nešto poput Hello, World!), i čitamo je znak po znak

#include #include #include void main () (FILE * input = NULL; char c; char bafer = (0); input = fopen ("D: /c/text.txt", "rt"); setbuf (ulaz, bafer); while ( ! feof (ulaz)) (c = fgetc (ulaz); printf ("% c \ n", c); printf ("% s \ n", bafer); _getch ();) fclose (ulaz);)

Možete vidjeti da su podaci već u baferu. Čitanje znak po znak se izvodi već iz bafera.

feof

Funkcija int feof (FILE * stream); vraća true ako je dostignut kraj datoteke. Ova funkcija je korisna kada trebate proći kroz cijeli fajl od početka do kraja. Neka postoji fajl sa tekstualnim sadržajem text.txt. Čitamo fajl karakter po znak i prikazujemo ga na ekranu.

#include #include #include void main () (FILE * input = NULL; char c; input = fopen ("D: /c/text.txt", "rt"); if (input == NULL) (printf ("Greška pri otvaranju datoteke") ; _getch (); izlaz (0);) while (! feof (ulaz)) (c = fgetc (ulaz); fprintf (stdout, "% c", c);) fclose (ulaz); _getch ();)

Sve bi bilo u redu, samo feof funkcija ne radi ispravno... To je zbog činjenice da koncept "kraja datoteke" nije definiran. Kada se koristi feof, greška se često javlja kada se posljednji pročitani podaci iznesu dva puta. To je zbog činjenice da se podaci upisuju u ulazni bafer, posljednje čitanje se javlja s greškom i funkcija vraća staru pročitanu vrijednost.

#include #include #include void main () (FILE * input = NULL; char c; input = fopen ("D: /c/text.txt", "rt"); if (input == NULL) (printf ("Greška pri otvaranju datoteke") ; _getch (); izlaz (0);) while (! feof (unos)) (fscanf (ulaz, "% c", & c); fprintf (stdout, "% c", c);) fclose (ulaz) ; _getch ();)

Ovaj primjer neće uspjeti (najvjerovatnije) i dvaput će ispisati posljednji znak datoteke.

Rješenje je ne koristiti feof. Na primjer, pohranite ukupan broj zapisa ili iskoristite činjenicu da fscanf, itd., obično vraća broj ispravno pročitanih i usklađenih vrijednosti.

#include #include #include void main () (FILE * input = NULL; char c; input = fopen ("D: /c/text.txt", "rt"); if (input == NULL) (printf ("Greška pri otvaranju datoteke") ; _getch (); izlaz (0);) while (fscanf (ulaz, "% c", & c) == 1) (fprintf (stdout, "% c", c);) fclose (ulaz); _getch ( ) ;)

Primjeri

1. U jednom fajlu su zapisana dva broja - dimenzije niza. Popunimo drugu datoteku nizom nasumičnih brojeva.

#include #include #include #include // Imena datoteka i dozvole #define INPUT_FILE "D: /c/input.txt" #define OUTPUT_FILE "D: /c/output.txt" #define ČITANJE_ONLY "r" #define WRITE_ONLY "w" // Maksimalna vrijednost za niz veličina #define MAX_DIMENSION 100 // Greška pri otvaranju datoteke #define ERROR_OPEN_FILE -3 void main () (FILE * inputFile, * outputFile; unsigned m, n; unsigned i, j; inputFile = fopen (INPUT_FILE, READ_ONLY); if ( input = NULL) (printf ("Greška pri otvaranju datoteke% s", INPUT_FILE); getch (); izlaz (ERROR_OPEN_FILE);) outputFile = fopen (OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) (printf ("Greška pri otvaranju datoteke % s ", OUTPUT_FILE); getch (); // Ako je datoteka otvorena za čitanje, onda se mora zatvoriti if (inputFile! = NULL) (fclose (inputFile);) exit (ERROR_OPEN_FILE);) fscanf (inputFile, "% ud% ud", & m, & n); ako (m> MAX_DIMENSION) (m = MAX_DIMENSION;) ako (n> MAX_DIMENSION) (n = MAX_DIMENSION;) srand (vrijeme (NULL)); za (i = 0; i< n; i++) { for (j = 0; j < m; j++) { fprintf(outputFile, "%8d ", rand()); } fprintf(outputFile, "\n"); } //Закрываем файлы fclose(inputFile); fclose(outputFile); }

2. Korisnik kopira datoteku i prvo bira način rada: datoteka se može poslati i na konzolu i kopirati u novu datoteku.

#include #include #include #define ERROR_FILE_OPEN -3 void main () (FILE * origin = NULL; FILE * output = NULL; char naziv datoteke; int mod; printf ("Unesite naziv datoteke:"); scanf ("% 1023s", naziv datoteke); origin = fopen (ime datoteke, "r"); if (origin == NULL) (printf ("Greška pri otvaranju datoteke% s", naziv datoteke); getch (); izlaz (ERROR_FILE_OPEN);) printf ("ulazak u način:"); scanf ( "% d", & mod); if (način == 1) (printf ("Unesite naziv datoteke:"); scanf ("% 1023s", naziv datoteke); output = fopen (ime datoteke, "w"); if (izlaz = = NULL) (printf ("Greška pri otvaranju datoteke% s", naziv datoteke); getch (); fclose (izvor); izlaz (ERROR_FILE_OPEN);)) else (output = stdout;) dok (! Feof (izvor)) ( fprintf (izlaz, "% c", fgetc (poreklo));) fclose (izlaz); fclose (izlaz); getch ();)

3. Korisnik unosi podatke sa konzole i oni se upisuju u datoteku dok se ne pritisne tipka esc. Provjerite program i pogledajte. kako se ponaša ako upišete backspace: šta se izlazi u datoteku, a šta na konzolu.

#include #include #include #define ERROR_FILE_OPEN -3 void main () (FILE * izlaz = NULL; char c; izlaz = fopen ("D: /c/test_output.txt", "w + t"); if (izlaz == NULL) (printf ("Greška pri otvaranju datoteke"); _getch (); izlaz (ERROR_FILE_OPEN);) za (;;) (c = _getch (); if (c == 27) (prekid;) fputc (c, izlaz); fputc ( c, stdout);) fclose (izlaz);)

4. Datoteka sadrži cijele brojeve. Pronađite maksimum od njih. Iskoristimo činjenicu da funkcija fscanf vraća broj objekata koji su pročitani i ispravno upareni. Svaki put treba vratiti broj 1.

#include #include #include #define ERROR_FILE_OPEN -3 void main () (FILE * input = NULL; int num, maxn, hasRead; input = fopen ("D: /c/input.txt", "r"); if (input == NULL) (printf ("Greška pri otvaranju datoteke"); _getch (); izlaz (ERROR_FILE_OPEN);) maxn = INT_MIN; hasRead = 1; dok (hasRead == 1) (hasRead = fscanf (ulaz, "% d", & num) if (hasRead! = 1) (nastavi;) if (broj>

Drugo rješenje je čitanje brojeva dok ne dođemo do kraja datoteke.

#include #include #include #include #define ERROR_FILE_OPEN -3 void main () (FILE * input = NULL; int num, maxn, hasRead; input = fopen ("D: /c/input.txt", "r"); if (input == NULL) (printf ("Greška pri otvaranju datoteke"); _getch (); izlaz (ERROR_FILE_OPEN);) maxn = INT_MIN; dok (! feof (unos)) (fscanf (ulaz, "% d", & num); if (num> maxn ) (maxn = num;)) printf ("maksimalni broj =% d", maxn); fclose (unos); _getch ();)

5. Fajl sadrži riječi: ruska riječ, tabela, engleska riječ, u nekoliko redova. Korisnik unosi englesku riječ, potrebno je prikazati rusku riječ.

Datoteka prijevoda izgleda otprilike ovako

Sunce sunce
olovka olovka
olovka hemijska olovka
vrata vrata
windows prozor
stolica stolica
fotelja stolica

i sačuvano u cp866 (OEM 866) kodiranju. Važno je da se i posljednji par riječi završava prijelazom na red.

Algoritam je sljedeći - čitamo red iz datoteke, pronalazimo tabulatorni znak u redu, zamjenjujemo tablični znak nulom, kopiramo rusku riječ iz bafera, kopiramo englesku riječ iz bafera, provjeravamo jednakost.

#include #include #include #include #define ERROR_FILE_OPEN -3 void main () (FILE * input = NULL; char bafer; char enWord; char ruWord; char usrWord; unsigned index; int length; int wasFound; input = fopen ("D: /c/input.txt "," r "); if (unos == NULL) (printf (" Greška pri otvaranju datoteke "); _getch (); izlaz (ERROR_FILE_OPEN);) printf (" unesite riječ: "); fgets (usrWord, 127, stdin ); wasFound = 0; while (! feof (input)) (fgets (bafer, 511, input); length = strlen (bafer); for (index = 0; index< length; index++) { if (buffer == "\t") { buffer = "\0"; break; } } strcpy(ruWord, buffer); strcpy(enWord, &buffer); if (!strcmp(enWord, usrWord)) { wasFound = 1; break; } } if (wasFound) { printf("%s", ruWord); } else { printf("Word not found"); } fclose(input); _getch(); }

6. Izbrojite broj redova u datoteci. Čitajmo datoteku znak po znak, računajući broj "\ n" znakova dok ne naiđemo na EOF karakter. EOF je poseban znak koji označava da je unos završen i da nema više podataka za čitanje. Funkcija vraća negativnu vrijednost u slučaju greške.
NAPOMENA: EOF je int, tako da morate koristiti int za čitanje znakova. Osim toga, EOF vrijednost nije definirana standardom.

#define _CRT_SECURE_NO_WARNINGS #include #include #include int cntLines (const char * ime datoteke) (int linije = 0; int bilo koji; // bilo koji tipa int, jer je EOF tipa int! FILE * f = fopen (ime datoteke, "r"); if (f == NULL ) (povrat -1;) do (bilo koji = fgetc (f); // printf ("% c", bilo koji); // otklanjanje grešaka if (bilo koji == "\ n") (linije ++;)) while ("% c", bilo koji); bilo koji! = EOF); ​​fclose (f); povratne linije;) void main () (printf ("% d \ n", cntLines ("C: /c/file.txt")); _getch (); )

Ru-Cyrl 18- tutorial Sypachev S.S. 1989-04-14 [email protected] Stepan Sypachev studenti

Još uvijek nije jasno? - pisati pitanja u poštansko sanduče

Top srodni članci