Cum se configurează smartphone-uri și PC-uri. Portal informativ
  • Acasă
  • știri
  • Lucrul cu două fișiere c. Scrierea - citirea informațiilor

Lucrul cu două fișiere c. Scrierea - citirea informațiilor

Pentru ușurință de referință, informațiile din dispozitivele de stocare sunt stocate sub formă de fișiere.

Fișier - zonă denumită memorie externa dedicat stocării matricei de date. Datele conținute în fișiere sunt de cea mai diversă natură: programe bazate pe algoritmice sau limbajul mașinii; date inițiale pentru funcționarea programelor sau rezultatele execuției programelor; texte arbitrare; imagini grafice etc.

Director (dosar, director) - o colecție numită de octeți pe un mediu de stocare, care conține numele subdirectoarelor și fișierelor, este utilizată în sistemul de fișiere pentru a simplifica organizarea fișierelor.

Sistemul de fișiere numită parte funcțională sistem de operare, care asigură executarea operațiunilor pe fișiere. Exemple de sisteme de fișiere sunt FAT (FAT - File Allocation Table), NTFS, UDF (utilizat pe CD-uri).

Există trei versiuni principale de FAT: FAT12, FAT16 și FAT32. Ele diferă prin adâncimea de biți a înregistrărilor din structura discului, adică numărul de biți alocați pentru stocarea numărului clusterului. FAT12 este folosit în principal pentru dischete (până la 4 KB), FAT16 pentru discuri mici, FAT32 pentru unități FLASH capacitate mare(până la 32 GB).

Luați în considerare structura Sistemul de fișiere folosind FAT32 ca exemplu.

Structura fișierului FAT32

Dispozitivele de memorie externe din sistemul FAT32 nu au byte, ci blochează adresare. Informațiile sunt scrise pe dispozitivul de memorie extern în blocuri sau sectoare.

Un sector este cea mai mică unitate adresabilă de stocare a informațiilor pe dispozitivele de stocare externe. De obicei, dimensiunea sectorului este fixată la 512 octeți. Pentru a mări spațiul de adrese al dispozitivelor de memorie externe, sectoarele sunt combinate în grupuri numite clustere.

Un cluster este o unire a mai multor sectoare, care poate fi considerată ca o unitate independentă cu anumite proprietăți. Proprietatea principală a unui cluster este dimensiunea sa, măsurată în numărul de sectoare sau numărul de octeți.

Sistemul de fișiere FAT32 are următoarea structură.

Clusterele utilizate pentru înregistrarea fișierelor sunt numerotate începând de la 2. De regulă, clusterul # 2 este folosit de directorul rădăcină, iar pornind de la clusterul # 3, este stocată o serie de date. Sectoarele utilizate pentru a stoca informațiile prezentate deasupra directorului rădăcină nu sunt grupate.
Dimensiunea minimă a fișierului de pe disc este de 1 cluster.

Sectorul de boot începe cu următoarele informații:

  • EB 58 90 - ramura neconditionata si semnatura;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 - numărul de octeți din sector (de obicei 512);
  • 1 octet - numărul de sectoare din cluster;
  • 2 octeți - numărul de sectoare de rezervă.

În plus, sectorul de boot conține următoarele informații importante:

  • 0x10 (1 octet) - numărul de tabele FAT (de obicei 2);
  • 0x20 (4 octeți) - numărul de sectoare de pe disc;
  • 0x2С (4 octeți) - numărul cluster-ului directorului rădăcină;
  • 0x47 (11 octeți) - etichetă de volum;
  • 0x1FE (2 octeți) - semnătură sectorul de boot(55 AA).

Sectorul de informații despre sistemul de fișiere conține:

  • 0x00 (4 octeți) - semnătură (52 52 61 41);
  • 0x1E4 (4 octeți) - semnătură (72 72 41 61);
  • 0x1E8 (4 octeți) - numărul de clustere libere, -1 dacă nu este cunoscut;
  • 0x1EC (4 octeți) - numărul ultimului cluster înregistrat;
  • 0x1FE (2 octeți) - semnătură (55 AA).

FAT conține informații despre starea fiecărui cluster de pe disc. Cei 2 octeți inferiori ai depozitului FAT F8 FF FF 0F FF FF FF FF (care corespunde stării clusterelor 0 și 1, care lipsesc fizic). În plus, starea fiecărui cluster conține numărul clusterului în care fișierul curent continuă sau următoarele informații:

  • 00 00 00 00 - clusterul este liber;
  • FF FF FF 0F - sfârșitul fișierului curent.
  • 8 octeți - numele fișierului;
  • 3 octeți - extensia fișierului;

Directorul rădăcină conține un set de înregistrări de informații pe 32 de biți pentru fiecare fișier, care conține următoarele informații:

În cazul lucrului cu nume lungi fișiere (inclusiv nume rusești), numele fișierului este codificat în sistemul de codificare UTF-16. În acest caz, 2 octeți sunt alocați pentru codificarea fiecărui caracter. În acest caz, numele fișierului este scris sub forma următoarei structuri:

  • 1 octet de secvență;
  • 10 octeți conțin cele mai puțin semnificative 5 caractere ale numelui fișierului;
  • atribut de 1 octet;
  • 1 octet rezervat;
  • 1 octet - verifica suma numele DOS;
  • 12 octeți conțin cele mai puțin semnificative 3 caractere ale numelui fișierului;
  • 2 octeți - numărul primului cluster;
  • alte personaje ale numelui lung.

Lucrul cu fișiere în limbajul C

Pentru un programator deschide fișierul este reprezentată ca o secvență de date citite sau scrise. Când un fișier este deschis, acesta este asociat cu Flux I/O... Informațiile de ieșire sunt scrise în flux, informațiile de intrare sunt citite din flux.

Când un flux este deschis pentru I/O, acesta se asociază cu o structură standard de tip FILE, care este definită în stdio.h. Structura FILE conține informatie necesara despre dosar.

Fișierul este deschis utilizând funcția fopen (), care returnează un pointer către o structură FILE, care poate fi folosită pentru operațiunile ulterioare cu fișierul.

FIȘIER * fopen (nume, tip);


nume - numele fișierului de deschis (inclusiv calea),
tipul este un indicator către un șir de caractere care determină cum se accesează fișierul:
  • "r" - deschideți un fișier pentru citire (fișierul trebuie să existe);
  • "w" - deschis dosar gol pentru înregistrare; dacă fișierul există, atunci conținutul său se pierde;
  • "a" - deschideți fișierul pentru scriere până la sfârșit (pentru adăugare); fisierul este creat daca nu exista;
  • "r +" - deschideți un fișier pentru citire și scriere (fișierul trebuie să existe);
  • "w +" - deschideți un fișier gol pentru citire și scriere; dacă fișierul există, atunci conținutul său se pierde;
  • „a +” - deschideți fișierul pentru citire și adăugare, dacă fișierul nu există, atunci este creat.

Valoarea returnată este un pointer către fluxul deschis. Dacă se întâlnește o eroare, este returnat NULL.

Funcția fclose () închide fluxul sau fluxurile asociate fișierelor deschise cu fopen (). Fluxul de închis este determinat de argumentul funcției fclose ().

Valoare returnată: valoarea 0, dacă fluxul a fost închis cu succes; EOF constantă dacă a apărut o eroare.

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

#include
int main () (
FIȘIER * fp;
nume caracter = "my.txt";
if ((fp = fopen (nume, "r")) == NULL)
{
printf ( "Fișierul nu poate fi deschis");
getchar ();
returnează 0;
}
// deschide fișierul cu succes
... // acțiuni necesare asupra datelor
fclose (fp);
getchar ();
returnează 0;
}

Citirea unui caracter dintr-un fișier:

char fgetc (flux);


Argumentul funcției este un pointer către un flux de tip FILE. Funcția returnează codul caracterului citit. Dacă se ajunge la sfârșitul fișierului sau apare o eroare, este returnată constanta EOF.

Scrierea unui caracter într-un fișier:

fputc (personaj, flux);

Argumentele funcției sunt un caracter și un pointer către un flux de tip FILE. Funcția returnează codul caracterului citit.

Funcțiile Fscanf () și fprintf () sunt similare funcții scanf() și printf (), dar funcționează cu fișiere de date și au primul argument, un pointer de fișier.

fscanf (flux, „Format de intrare”, argumente);

Înregistrați informații în fisier text am invatat deja. - Dacă nu ai învățat, vezi ultimul articol. Spune și descrie în detaliu

Dar dacă fișierul există deja și trebuie să citim informații din el pentru procesare? Din fericire, acest lucru este și destul de simplu. Permiteți-mi să vă reamintesc că există mai multe opțiuni pentru implementarea acestei sarcini, am descris doar una dintre ele. Descris este cel care din anumite motive personal mi se pare cel mai ușor de perceput.

#include

int main ()
{
char s1 //Variabila va citi șirul
ifstream în (“C: \\\ FromC \\ myfile.txt”); //Deschiderea fișierului pentru a citi informații
în >> s1; //citește rândul
în .close () //Închideți fișierul

cout<Afișarea valorii s1 pe ecran
returnează 0;
}

Iată cel mai simplu program pentru a citi prima linie dintr-un fișier text situat de-a lungul căii
C: \\\ DinC \\ fişierul meu.txt -
Deoarece aceasta este o continuare a ultimului articol, am decis să folosesc fișierul pe care l-am creat acolo. Probabil că nu ar trebui să fie dificultăți cu asta.
Dar să revenim la cod. Mai întâi, deschidem fișierul pentru a citi informațiile din acesta, pentru aceasta folosim comanda ifstream,între paranteze indicăm fie numele fișierului, fie calea către fișier, așa cum am făcut eu. („C: \\\ FromC \\ myfile.txt”);
Când am deschis fișierul pentru a citi ceva din el, am declarat o variabilă ca char -
char s1
Acum trebuie doar să atribuim valoarea șirului din fișier variabilei. Facem asta ca o echipă în
Acordați atenție suporturilor unghiulare în >>
De fapt, așa cum se vede din comentariile la codul programului, pentru ca variabila să atribuie valoarea citită, trebuie să o scriem după în >>
în >> s1;

Fără special sarcina dificila acest lucru nu pare să fie cazul, mai ales dacă ați stăpânit deja perfect și ați învățat cum să utilizați materialul articolului anterior - totul este absolut la fel, doar 2 comenzi sunt diferite

Crearea unui fișier și scrierea informațiilor în el C++

ofstream afară ( Nume de fișier );
afară<< (Șir scris);
afară.închide ();
=============================

Citirea textului dintr-un fișier și afișarea textului pe ecran în C++

ifstream în (Nume de fișier );
în>> (Citim rândul);
în.închide ();(Închide fișierul)
============================
Vom scrie program simplu care va citi textul introdus de la tastatură și îl va scrie într-un fișier:

#include
#include

int main ()
{
\\ 3 rânduri viitoare
clrscsr (); // Curățarea ecranului

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

/ * Să începem să lucrăm cu fișierul * /
ofstream out („C: \\\ FromC \\ myfile.txt”); //Deschiderea fișierului pentru scriere
afară<Scriem primul rând
afară<Scriem a doua linie
afară<Scriem a treia linie
afară .închide (); //Închideți fișierul

// Setați variabilele la zero

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


ifstream în („C: \\\ FromC \\ myfile.txt”);
în >> a >> b >> c; //Citim fiecare rând nou într-o nouă variabilă
în .închidere (); //Închideți fișierul

/* */

pentru (i = 0; a! = * „”; i ++)
{
dacă (i> dimensiunea (a)) pauză;
cout<

}
cout<<“\n” ; \\

/* */


{
dacă (i> dimensiunea (b)) pauză;
cout<
}
cout<<“\n” ; \\ Mutați cursorul pe o linie nouă

/* */

pentru (i = 0; с! = * „”; i ++)
{
dacă (i> dimensiunea (c)) pauză;
cout<<с ;
}

returnează 0;
}
===================

În exemplele de mai sus, există unul astfel IMENS defect. Dacă încercăm să introducem o linie care conține spații, atunci programul nu va funcționa așa cum avem nevoie. Probabil, nu numai eu, ci și mulți alți oameni am dat peste această eroare. Prin urmare, las codul dat incorect, astfel încât să puteți vedea ce ați putea întâlni.

Din moment ce nu există cărți acasă, am început din nou să caut pe internet și am dat peste o mulțime de tot felul de prostii complicate. Totuși, am găsit cumva o soluție la problema mea.
M-a ajutat să citesc asta cout sprijină metodele sale. Și pe Internet, toate sfaturile merg la utilizarea funcției getline Din fericire, am găsit foarte repede cum să folosesc această funcție și apoi am folosit-o în cod.
În general, merită menționat și descris această funcție, dar până acum nu o înțeleg cu adevărat, înțeleg doar că trebuie folosită și înțeleg cum, așa că dau un exemplu mai corect al programului nostru dezvoltat:

#include
#include

int main ()
{
char a, b, c; \\ 3 rânduri viitoare
clrscsr (); // Curățarea ecranului

/ * Introduceți valori pentru variabile * /

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 (); //După introducerea valorilor, ștergeți ecranul

/ * Să începem să lucrăm cu fișierul * /
ofstream out („C: \\\ FromC \\ myfile.txt”); // Deschiderea fișierului pentru scriere
afară<
Scriem primul rând
afară<Scriem a doua linie
afară<Scriem a treia linie
afară .închide (); //Închideți fișierul

// Setați variabilele la zero

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

/ * Continuăm să lucrăm cu fișierul * /

dacă flux în („C: \\\ FromC \\ myfile.txt”);
in.getline (a, sizeof (a));// A
in.getline (b, sizeof (b));// Citim o linie într-o variabilă b
in.getline (c, sizeof (c)); // Citim o linie într-o variabilă c
în .închidere (); //Închideți fișierul

/* Citim primul rând caracter cu caracter și îl afișăm pe ecran */

pentru (i = 0; a! = * „”; i ++)
{
dacă (i> dimensiunea (a)) pauză;
cout<

}
cout<<“\n” ; \\ Mutați cursorul pe o linie nouă

/* Citim a doua linie caracter cu caracter și o afișăm pe ecran */

pentru (i = 0; b! = * „”; i ++)
{
dacă (i> dimensiunea (b)) pauză;
cout<
}
cout<<“\n” ; \\ Mutați cursorul pe o linie nouă

/* Citim a treia linie caracter cu caracter și o afișăm pe ecran */

pentru (i = 0; с! = * „”; i ++)
{
dacă (i> dimensiunea (c)) pauză;
cout<<с[i];
}

getch (); \\Se așteaptă apăsarea tastei Enter
returnează 0;
}
===================

În acest material, este analizat un exemplu de citire a informațiilor personaj cu caracter. Deoarece nu am descris cum să lucrez cu variabile precum char, atunci începătorii pot întâmpina unele inconveniente în perceperea codului. Doar că nu știam care este tipul char are unele particularități și cred că totul este mai simplu. Prin urmare, câteva puncte de neînțeles ale programului de mai sus pot fi citite în articolul următor. lucrul cu char v C++ pentru începători

În rest, exemplul dat despre cum să citești linii dintr-un fișier text în C++ ar trebui să fie disponibil și destul de ușor de înțeles. Aceasta nu este opțiunea optimă de implementare acum și am omis câteva puncte importante, dar din moment ce începem să învățăm limbajul C++, acest lucru este destul de suficient pentru moment. Mai târziu, probabil că voi ajunge la punctul în care am ratat-o, dar acum trebuie să iau doar elementele esențiale.

Daca am inteles acest material impreuna cu tine inseamna ca am facut un mic pas catre profesionalismul nostru.

Notă:
pauză;- Aceasta este comanda care iese din buclă. Avem dacă contorul de cicluri pentru devine mai mare decât dimensiunea declarată a variabilei char, apoi ieșim forțat din buclă
!= – aceasta este condiția noastră. Această condiție este indicată de inegalitate
dacă (a! = b)- Citește ca și cum A nu este egal b

endl; - Aceasta este mutarea cursorului pe o nouă linie în interiorul consolei (din câte am înțeles)
Această comandă este similară cu „\ N”

Majoritatea programelor de calculator funcționează cu fișiere și, prin urmare, devine necesară crearea, ștergerea, scrierea, citirea, deschiderea fișierelor. Ce este un fișier? Un fișier este un set numit de octeți care poate fi stocat pe un dispozitiv de stocare. Ei bine, acum este clar că un fișier este înțeles ca o anumită secvență de octeți, care are un nume propriu, unic, de exemplu un fișier .txt. Fișierele cu aceleași nume nu pot fi în același director. Numele fișierului înseamnă nu numai numele, ci și extensia sa, de exemplu: fișier.txt și fișier.dat fișiere diferite, deși au același nume. Există un astfel de concept precum numele complet al fișierelor - aceasta este adresa completă a directorului de fișiere cu numele fișierului, de exemplu: D: \ docs \ file.txt. Este important să înțelegeți aceste concepte de bază, altfel va fi dificil să lucrați cu fișiere.

Pentru a lucra cu fișiere, trebuie să conectați fișierul antet . V sunt definite mai multe clase și sunt incluse fișiere de antet fisier de intrare si ieșire fișier.

File I / O este similar cu I / O standard, singura diferență este că I / O se face nu pe ecran, ci către un fișier. Dacă I/O la dispozitivele standard se efectuează folosind obiectele cin și cout, atunci pentru a organiza I/O fișier, este suficient să creați propriile obiecte care pot fi utilizate în mod similar cu operatorii cin și cout.

De exemplu, trebuie să creați un fișier text și să scrieți în el linia Lucru cu fișierele în C++. Pentru a face acest lucru, trebuie să efectuați următorii pași:

  1. creați un obiect din clasa ofstream ;
  2. asocierea unui obiect de clasă cu un fișier în care să fie scris;
  3. scrieți o linie într-un fișier;
  4. închideți fișierul.

De ce este necesar să se creeze un obiect al clasei ofstream și nu al clasei ifstream? Deoarece trebuie să scrieți într-un fișier și dacă aveți nevoie să citiți date dintr-un fișier, ar fi creat un obiect din clasa ifstream.

// creează un obiect de scris în fișierul de flux / * nume obiect * /; // un obiect al clasei ofstream

Să numim obiectul - fout. Iată ce obțineți:

Ofstream fout;

De ce avem nevoie de un obiect? Obiectul este necesar pentru a putea scrie în fișier. Obiectul a fost deja creat, dar nu este asociat cu fișierul în care doriți să scrieți șirul.

Fout.open ("cppstudio.txt"); // leagă obiectul la fișier

Prin operația punct, obținem acces la metoda clasei deschise (), în parantezele căreia indicăm numele fișierului. Fișierul specificat va fi creat în directorul curent cu programul. Dacă există un fișier cu acest nume, fișierul existent va fi suprascris cu cel nou. Deci, fișierul este deschis, rămâne să scrieți linia necesară în el. Acest lucru se face astfel:

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

Folosind operațiunea stream împreună cu obiectul fout, File Worker în linia C++ este scrisă într-un fișier. Deoarece nu mai este necesară modificarea conținutului fișierului, acesta trebuie închis, adică obiectul trebuie separat de fișier.

Fout.close (); // închide fișierul

Rezultat - a fost creat un fișier cu linia Lucrul cu fișiere în C++.

Pașii 1 și 2 pot fi combinați, adică creați un obiect pe o linie și legați-l la un fișier. Acest lucru se face astfel:

Ofstream fout ("cppstudio.txt"); // creează un obiect al clasei ofstream și conectează-l la fișierul cppstudio.txt

Să combinăm tot codul și să obținem următorul program.

// file.cpp: definește punctul de intrare pentru aplicația consolă. #include „stdafx.h” #include folosind namespace std; int main (int argc, char * argv) (ofstream fout ("cppstudio.txt"); // creează un obiect din clasa ofstream pentru înregistrare și leagă-l la fișierul cppstudio.txt fout<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

Rămâne să verificăm corectitudinea programului și pentru aceasta deschidem fișierul cppstudio.txt și ne uităm la conținutul său, ar trebui să fie - Lucrul cu fișiere în C++.

  1. creați un obiect din clasa ifstream și asociați-l cu fișierul din care se va face citirea;
  2. citește dosarul;
  3. închideți fișierul.
// file_read.cpp: definește punctul de intrare pentru aplicația consolă. #include „stdafx.h” #include #include folosind namespace std; int main (int argc, char * argv) (setlocale (LC_ALL, "rus"); // afișarea corectă a caracterului buff cu alfabet chirilic; // buffer pentru stocarea intermediară a textului citit din fișierul ifstream fin ("cppstudio.txt "); // a deschis fișierul pentru a citi fin >><< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку system("pause"); return 0; }

Programul arată două moduri de citire dintr-un fișier, primul folosește operația de transfer în flux, al doilea folosește funcția getline () ... În primul caz, se citește doar primul cuvânt, iar în al doilea caz se citește un șir de 50 de caractere. Dar, din moment ce au rămas mai puțin de 50 de caractere în fișier, caracterele sunt citite, inclusiv, până la ultimul. Rețineți că citiți a doua oară (linia 17) a continuat, după primul cuvânt, și nu de la început, din moment ce primul cuvânt a fost citit înlinia 14... Rezultatul programului este prezentat în Figura 1.

Lucrul cu fișiere în C++ Apăsați orice tastă pentru a continua. ... ...

Figura 1 - Lucrul cu fișiere în C++

Programul a funcționat corect, dar nu este întotdeauna cazul, chiar dacă totul este în ordine cu codul. De exemplu, numele unui fișier inexistent a fost transmis programului sau a fost făcută o eroare în nume. Ce atunci? În acest caz, nu se va întâmpla absolut nimic. Fișierul nu va fi găsit, ceea ce înseamnă că nu este posibil să îl citiți. Prin urmare, compilatorul va ignora liniile în care fișierul este accesat. Ca rezultat, programul se va închide corect, dar nimic nu va fi afișat pe ecran. S-ar părea că aceasta este o reacție complet normală la o astfel de situație. Dar un utilizator obișnuit nu va înțelege care este problema și de ce linia din fișier nu a apărut pe ecran. Deci, pentru a clarifica totul, C++ oferă o astfel de funcție - is_open (), care returnează valori întregi: 1 - dacă fișierul a fost deschis cu succes, 0 - dacă fișierul nu a fost deschis. Să modificăm programul cu deschiderea fișierului, astfel încât dacă fișierul nu a fost deschis, să fie afișat un mesaj corespunzător.

// file_read.cpp: definește punctul de intrare pentru aplicația consolă. #include „stdafx.h” #include #include folosind namespace std; int main (int argc, char * argv) (setlocale (LC_ALL, "rus"); // afișarea corectă a alfabetului chirilic char buff; // buffer pentru stocarea intermediară a textului citit din fișierul ifstream fin ("cppstudio.doc "); // ( INCLUS NUMELE FIȘIER INCORECT) dacă (! Fin.is_open ()) // dacă fișierul nu este deschis<< "Файл не может быть открыт!\n"; // сообщить об этом else { fin >> buff; // citește primul cuvânt din fișierul cout<< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку } system("pause"); return 0; }

Rezultatul programului este prezentat în Figura 2.

Fișierul nu poate fi deschis! Apăsați orice tastă pentru a continua. ... ...

Figura 2 - Lucrul cu fișiere în C++

După cum puteți vedea din Figura 2, programul a raportat incapacitatea de a deschide fișierul. Prin urmare, dacă programul lucrează cu fișiere, este recomandat să utilizați această funcție, is_open (), chiar dacă sunteți sigur că fișierul există.

Moduri de deschidere a fișierelor

Modurile de deschidere a fișierelor stabilesc modul în care sunt utilizate fișierele. Pentru a seta modul în clasa ios_base, sunt furnizate constante care determină modul de deschidere a fișierelor (vezi Tabelul 1).

Modurile de deschidere a fișierelor pot fi setate direct la crearea unui obiect sau la apelarea funcției de deschidere (). .

Ofstream fout ("cppstudio.txt", ios_base :: app); // deschideți fișierul pentru a adăuga informații la sfârșitul fișierului fout.open ("cppstudio.txt", ios_base :: app); // deschideți fișierul pentru a adăuga informații la sfârșitul fișierului

Modurile de deschidere a fișierelor pot fi combinate folosind operația logică pe biți sau| , de exemplu: ios_base :: out | ios_base :: trunc - deschideți un fișier pentru scriere, după ce îl ștergeți.

Obiectele clasei ofstream, atunci când sunt legate cu fișiere, conțin implicit modurile de deschidere a fișierelor ios_base :: out | ios_base :: trunc . Adică, fișierul va fi creat dacă nu există. Dacă fișierul există, atunci conținutul acestuia va fi șters, iar fișierul în sine va fi gata de scris. Obiectele clasei ifstream care se leagă cu un fișier au modul implicit de deschidere a fișierului ios_base :: in - fișierul este deschis doar pentru citire. Modul de deschidere a fișierului este numit și steag, pentru lizibilitate în viitor vom folosi chiar acest termen. Nu toate steaguri sunt listate în Tabelul 1, dar acestea ar trebui să fie suficiente pentru început.

Rețineți că steagurile ate și aplicația sunt foarte asemănătoare ca descriere, ambele mută indicatorul la sfârșitul fișierului, dar stegulețul aplicației permite scrierea doar la sfârșitul fișierului, iar stegulețul ate mută pur și simplu steag-ul la sfârșit. a fișierului și nu limitează locațiile de scriere.

Să dezvoltăm un program care, folosind operația sizeof (), va calcula caracteristicile tipurilor de date de bază în C++ și le va scrie într-un fișier. Specificații:

  1. numărul de octeți alocați pentru tipul de date
  2. valoarea maximă pe care o poate stoca un anumit tip de date.

Scrierea într-un fișier trebuie făcută în următorul format:

/ * Tip de date octet valoare max bool = 1 255,00 char = 1 255,00 scurt int = 2 32767.00 unsigned short int = 2 65535.00 int = 4 2147483647.00 unsigned int = 4 4294967295.00 lung int = 4 2147483647.00 unsigned long int = 4 4294967295.00 float = 4 2147483647.00 float lung = 8 9223372036854775800,00 dublu = 8 9223372036854775800,00 * /

Un astfel de program a fost deja dezvoltat mai devreme în secțiune, dar acolo toate informațiile despre tipurile de date au fost transmise la dispozitivul de ieșire standard și trebuie să refacem programul, astfel încât informațiile să fie scrise într-un fișier. Pentru a face acest lucru, trebuie să deschideți fișierul în modul de înregistrare, cu trunchierea preliminară a informațiilor despre fișierul curent ( linia 14). Odată ce fișierul este creat și deschis cu succes (liniile 16 - 20), în loc de declarația cout, în linia 22 utilizați obiectul fout. astfel, în loc de un ecran, informațiile despre tipul de date sunt scrise într-un fișier.

// write_file.cpp: definește punctul de intrare pentru aplicația consolă. #include „stdafx.h” #include #include // lucrează cu fișierele #include // Manipulatoare I/O folosind namespace std; int main (int argc, char * argv) (setlocale (LC_ALL, "rus"); // leagă obiectul cu fișierul, în timp ce fișierul este deschis în modul de scriere, după eliminarea tuturor datelor din fluxul fout ("data_types. txt", ios_base :: out | ios_base :: trunc); if (! fout.is_open ()) // dacă fișierul nu a fost deschis (cout<< "Файл не может быть открыт или создан\n"; // напечатать соответствующее сообщение return 1; // выполнить выход из программы } fout << " data type " << "byte" << " " << " max value "<< endl // anteturi de coloană <<"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; }

Este imposibil să nu observați că modificările din program sunt minime și toate datorită faptului că intrarea / ieșirea standard și intrarea / ieșirea fișierelor sunt utilizate exact în același mod. La finalul programului, la oralinia 45am închis în mod explicit fișierul, deși nu este obligatoriu, este considerat o bună practică de programare. Este demn de remarcat faptul că toate funcțiile și manipulatoarele utilizate pentru formatarea I/O standard sunt relevante și pentru I/O fișier. Prin urmare, nu au existat erori atunci când operatorul cout a fost înlocuit cu un obiect fout.

Lucrul cu fișiere text în C++.

Există două tipuri principale de fișiere: text și binare. Fișierele permit utilizatorului să citească cantități mari de date direct de pe disc, fără a le introduce de la tastatură.

    Text sunt apelate fișiere formate din orice caractere. Ele sunt organizate în linii, fiecare dintre acestea se termină cu un caracter de final de linie. Sfârșitul fișierului în sine este indicat de simbolul „sfârșitul fișierului”. Când scrieți informații într-un fișier text, care poate fi vizualizat folosind orice editor de text, toate datele sunt convertite într-un tip de caracter și stocate sub formă de caractere.

    V binar fișiere, informațiile sunt citite și scrise sub formă de blocuri de o anumită dimensiune, în care pot fi stocate date de orice tip și structură.

Pentru a lucra cu fișiere, special tipuri de date numit cursuri... curgere ifstream servește pentru a lucra cu fișiere în modul de citire și ofstreamîn modul înregistrare. Pentru a lucra cu fișiere atât în ​​modul de scriere, cât și în modul de citire, utilizați fluxul fstream.

În programele C++, atunci când lucrați cu fișiere text, trebuie să includeți bibliotecile iostream și fstream.

Pentru a scrie date într-un fișier text, trebuie să:

    descrie o variabilă de tip de flux.

    scoateți informații într-un fișier.

    asigurați-vă că închideți fișierul.

Pentru citiri date dintr-un fișier text, trebuie să:

    descrie o variabilă de tip ifstream.

    deschideți fișierul folosind funcția de deschidere.

    închideți fișierul.

Înregistrare informații într-un fișier text

    După cum am menționat mai devreme, pentru a începe să lucrați cu un fișier text, trebuie să declarați o variabilă de tip ofstream. De exemplu, așa:

    O variabilă F va fi creată pentru a scrie informațiile în fișier.

    Următorul pas este să deschideți fișierul pentru scriere. În general, operatorul de deschidere a fluxului va arăta astfel:

F.open („fișier”, mod);

Aici F este o variabilă, descrisă ca ofstream,

fișier - numele complet al fișierului de pe disc,

mod - mod de operare cu fișierul deschis.

Vă rugăm să rețineți că trebuie să utilizați o bară oblică dublă atunci când specificați numele complet al fișierului. De exemplu, numele complet al fișierului noobs.txt aflat în folderul jocului de pe unitatea D: ar trebui scris astfel:

D: \\ joc \\ noobs.txt.

Fișierul poate fi deschis în unul dintre următoarele moduri:

ios :: in - deschideți un fișier în modul de citire a datelor, acest mod este modul implicit pentru fluxurile ifstream;

ios :: out - deschideți un fișier în modul de înregistrare a datelor (informațiile despre fișierul existent sunt distruse), acest mod este modul implicit pentru fluxurile de flux;

ios :: app - deschide un fișier în modul de scriere a datelor până la sfârșitul fișierului;

ios :: ate - trece la sfârșitul unui fișier deja deschis;

ios :: trunc - șterge fișierul, la fel se întâmplă și în modul ios :: out;

ios :: nocreate - nu deschideți fișierul dacă nu există;

ios :: noreplace - nu deschideți un fișier existent.

Parametrul mode poate fi absent, în acest caz fișierul este deschis în modul implicit pentru acest flux.

După deschiderea cu succes a fișierului (în orice mod), variabila F va stoca adevărat, altfel fals. Aceasta va verifica corectitudinea operațiunii de deschidere a fișierului.

Puteți deschide fișierul (luați ca exemplu fișierul D: \\ joc \\ noobs.txt) în modul de înregistrare în unul dintre următoarele moduri:

// primul cale

din fluxul F;

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

// a doua cale, modul ios :: out este implicit

// pentru curgereofstream

din fluxul F;

// a treia cale combină descrierea variabilei și fluxul de tip

// și deschideți fișierul într-o singură instrucțiune

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

După deschiderea fișierului în modul de scriere, va fi creat un fișier gol, în care se va putea scrie informații.

Dacă doriți să deschideți un fișier existent în modul de pre-scriere, utilizați valoarea aplicației ios :: ca mod.

După deschiderea unui fișier în modul de scriere, puteți scrie în el în același mod ca pe ecran, doar în locul dispozitivului de ieșire standardcouttrebuie să specificați numele fișierului deschis.

De exemplu, pentru a scrie variabila a în fluxul F, operatorul de ieșire va arăta astfel:

Pentru ieșirea secvențială în fluxul G de variabile b, c, d, operatorul de ieșire va deveni:

G<

Fluxul este închis folosind operatorul:

EXEMPLU:

Creați un fișier text D: \\ joc \\ noobs.txt și scrieți n numere reale în el.

#include „stdafx.h”

#include

#include

#include

folosind namespace std;

int main ()

setlocale (LC_ALL, "RUS");

int i, n;

dublu a;

// descrie un flux pentru scrierea datelor într-un fișier

ofstream f;

// deschideți fișierul în modul de scriere,

//modulios:: afarăinstalat implicit

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

// introduceți numărul de numere reale

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

// buclă pentru introducerea numerelor reale

// și scrieți-le într-un fișier

pentru (i = 0; i

cout<<"a=";

// introduceți un număr

cin >> a;

f<

// închide fluxul

f.închidere ();

sistem („pauză”);

returnează 0;

_______________________________________________________________

Pentru a citi informații dintr-un fișier text, trebuie să declarați o variabilă de acest tip ifstream... După aceea, trebuie să deschideți fișierul pentru citire folosind operatorul deschis... Dacă variabila se numește F, atunci primii doi operatori vor fi astfel:

F.open ("D: \\ joc \\ noobs.txt", ios :: în);

După deschiderea unui fișier în modul de citire, puteți citi informațiile din acesta în același mod ca și de la tastatură, doar în loc decinspecificați numele fluxului din care vor fi citite datele.

De exemplu, pentru a citi din fluxul F în variabila a, instrucțiunea de intrare ar arăta astfel:

Două numere dintr-un editor de text sunt considerate separate dacă există cel puțin unul dintre caracterele între ele: spațiu, tabulare, caracter de final de linie. Este bine dacă programatorul știe dinainte câte și ce valori sunt stocate într-un fișier text. Cu toate acestea, tipul de valori stocate în fișier este adesea cunoscut pur și simplu, iar numărul acestora poate varia. Când rezolvați această problemă, trebuie să citiți valorile din fișier pe rând și, înainte de fiecare citire, verificați dacă s-a ajuns la sfârșitul fișierului. Pentru aceasta există o funcție F. eof().

Aici F este numele fluxului.Funcția returnează o valoare booleană: adevărat sau fals, în funcție de sfârșitul fișierului. Prin urmare, bucla pentru citirea conținutului întregului fișier poate fi scrisă astfel:

// aranjați să citiți valori dintr-un fișier, executați

// bucla se va întrerupe când ajungem la sfârșitul fișierului,

// în acest caz F.eof () va returna adevărat

în timp ce (! F.eof ())

EXEMPLU:

Numerele reale sunt stocate în fișierul text D: \\ joc \\ noobs.txt, afișați-le pe ecran și calculați numărul lor.

#include „stdafx.h”

#include

#include

#include

#include

folosind namespace std;

int main ()

setlocale (LC_ALL, "RUS");

int n = 0;

plutire a;

fstream F;

// deschideți fișierul în modul citire

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

// dacă fișierul a fost deschis corect, atunci

// buclă pentru citirea valorilor dintr-un fișier; execuția ciclului va fi întreruptă,

// când ajungem la sfârșitul fișierului, în acest caz F.eof () va returna true.

în timp ce (! F.eof ())

// citește următoarea valoare din fluxul F în variabila a

F >> a;

// afișează pe ecran valoarea variabilei a

cout<

// crește numărul de numere citite

// închide fluxul

F.close ();

// introduceți pe ecran numărul de numere citite

cout<<"n="<

// dacă fișierul a fost deschis incorect, atunci rezultatul

// mesaje despre absența unui astfel de fișier

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

sistem („pauză”);

returnează 0;

C++. Gestionarea fișierelor binare

Când scrieți informații într-un fișier binar, caracterele și numerele sunt scrise ca o secvență de octeți.

Pentru a scrie date într-un fișier binar, aveți nevoie de:

    descrieți o variabilă de fișier de tip FAIL * folosind instrucțiunea FILE * nume de fișier;. Aici filename este numele variabilei în care va fi stocat indicatorul fișierului.

    scrieți informații în fișier folosind funcția fwrite

Pentru a citit b date dintr-un fișier binar, trebuie să:

    descrie o variabilă de tip FILE *

    deschideți fișierul cu funcția fopen

    închideți fișierul folosind funcția fclose

Funcții de bază necesare pentru a lucra cu binare.

Pentru descoperiri fișier, funcția fopen este destinată.

FILE * fopen (const * nume de fișier, const char * mod)

Aici filename este un șir care stochează numele complet al fișierului de deschis, mode este un șir care definește modul de lucru cu fișierul; sunt posibile următoarele valori:

„Rb” - deschideți un fișier binar în modul de citire;

"Wb" - creați un fișier binar pentru scriere; dacă există, atunci conținutul său este șters;

„Ab” - creați sau deschideți un fișier binar pentru a adăuga la sfârșitul fișierului;

„Rb +” - deschideți un fișier binar existent în modul citire și scriere;

„Wb +” - deschideți un fișier binar în modul citire/scriere, fișierul existent este șters;

„Ab +” - un fișier binar este deschis sau creat pentru a corecta informațiile existente și pentru a adăuga informații noi la sfârșitul fișierului.

Funcția returnează NULL în variabila fișier f dacă fișierul nu este deschis cu succes. După deschiderea fișierului, al 0-lea octet al acestuia este disponibil, indicatorul fișierului este egal cu 0, a cărui valoare este deplasată cu numărul de octeți citiți (scriși) pe măsură ce este citit sau scris. Valoarea curentă a indicatorului de fișier este numărul de octeți, începând de la care va avea loc operația de citire sau scriere.

Pentru închidere fișier, funcția fclose este destinată

int fclose (FIȘIER * nume fișier);

Returnează 0 la închiderea cu succes a fișierului și NULL în caz contrar.

Funcția de eliminare este pentru ştergerea fișiere.

int remove (const char * nume de fișier);

Această funcție elimină un fișier numit fileema de pe disc. Fișierul de șters trebuie să fie închis. Funcția returnează diferit de zero dacă fișierul nu a putut fi șters.

Pentru redenumire fișiere, funcția de redenumire este destinată:

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

Primul parametru este vechiul nume al fișierului, al doilea este cel nou. Returnează 0 la succes.

Citind dintr-un fișier binar se face folosind funcția fread:

fread (void * ptr, size, n, FILE * filename);

Funcția fread citește n elemente cu dimensiunea dimensiunii din numele fișierului într-o matrice ptr. Funcția returnează numărul de elemente citite. După citirea din fișier, indicatorul acestuia este deplasat cu n * octeți de dimensiune.

Înregistrare la un fișier binar se face folosind funcția fwrite:

fwrite (const void * ptr, size, n, FILE * filename);

Funcția fwrite scrie n elemente de dimensiune în numele fișierului din matricea ptr. Funcția returnează numărul de elemente scrise. După scrierea informațiilor în fișier, indicatorul este deplasat cu n * octeți de dimensiune.

Pentru control la sfârșitul fișierului există o funcție feof:

int feof (FIȘIER * nume fișier);

Returnează diferit de zero dacă s-a ajuns la sfârșitul fișierului.

EXEMPLU:

Creați un fișier binar D: \\ joc \\ noobs.dat și scrieți în el un număr întreg n și n numere reale.

#include „stdafx.h”

#include

folosind namespace std;

int main ()

setlocale (LC_ALL, "RUS");

int n, i;

dublu a;

// creează un fișier binar în modul de scriere

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

// intrare numerelen

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

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

// buclă pentru introducerea a n numere reale

pentru (i = 0; i

// introducerea următorului număr real

cout<<"a=";

cin >> a;

// scrie un număr real într-un fișier binar

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

// închide fişier

fclose (f);

sistem („pauză”);

returnează 0;

EXEMPLU:

Afișați conținutul fișierului binar D: \\ joc \\ noobs.dat creat în sarcina anterioară

#include „stdafx.h”

#include

folosind namespace std;

int main ()

setlocale (LC_ALL, "RUS");

int n, i;

dublu * a;

DOSAR * f; // descrie variabila fișier

// deschide un fișier binar existent în modul citire

// citește din fișier un număr întreg în variabila n

// afișează n pe ecran

cout<<"n="<

// alocarea memoriei pentru o matrice de n numere

a = dublu nou [n];

// citește n numere reale din fișier în tabloul a

// afișează matricea pe ecran

pentru (i = 0; i

cout<

cout<

// închide fişier

fclose (f);

sistem („pauză”);

returnează 0;

Fisier binar- structura secventiala a datelor, dupa deschiderea fisierului este disponibil primul octet stocat in acesta. Puteți scrie sau citi secvențial date dintr-un fișier. Să presupunem că doriți să numărați al cincisprezecelea număr și apoi primul. Cu acces secvenţial, acest lucru se poate face în felul următor:

int n, i;

dublu a;

DOSAR * f;

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

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

fclose (f);

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

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

fclose (f);

După cum puteți vedea, citirea numerelor dintr-un fișier în acest fel și apoi redeschiderea fișierului nu este cea mai convenabilă modalitate. Este mult mai convenabil să folosiți funcția fseek pentru a muta indicatorul fișierului pe un octet dat.

int fseek (FIȘIER * nume fișier, offset int lung, origine int);

Funcția setează indicatorul la poziția curentă a fișierului F în funcție de valoarea originii și offset-ului. Parametrul offset este egal cu numărul de octeți cu care pointerul fișierului va fi decalat față de originea specificată de parametrul de origine. Parametrul de origine trebuie să fie una dintre următoarele valori de offset, așa cum sunt definite în antetul stdio.h:

SEEK_SET - de la începutul fișierului;

SEEK_CUR - din pozitia curenta;

SEEK_END - de la sfârșitul fișierului.

Funcția returnează zero dacă operația are succes, diferit de zero dacă apare o eroare în timpul executării unui offset

Funcția fseek implementează de fapt accesul direct la orice valoare din fișier. Trebuie doar să știți locația (numărul de octeți) a valorii din fișier. Să ne uităm la utilizarea accesului direct în binare folosind exemplul de rezolvare a următoarei probleme.

EXEMPLU

În fișierul binar generat anterior D: \\ joc \\ noobs.dat, schimbați cele mai mari și cele mai mici numere reale.

Algoritmul de rezolvare a problemei constă din următoarele etape:

    citirea celor reale din fișier în matrice a.

    căutați în tabloul a valorile maxime (max) și minime (min) și numerele acestora (imax, imin).

    mutați indicatorul fișierului la valoarea maximă și scrieți min.

    mutați indicatorul fișierului la valoarea minimă și scrieți max.

Mai jos este textul programului pentru rezolvarea problemei cu comentarii.

#include „stdafx.h”

#include

folosind namespace std;

int main ()

setlocale (LC_ALL, "RUS");

int n, i, imax, imin;

dublu * a, max, min;

DOSAR * f;

// deschideți fișierul în modul citire și scriere

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

// citește suma din fișier în variabila n

// numere reale în fișier

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

cout<<"n="<

// alocă memorie pentru stocarea numerelor reale,

// care va fi stocat în tabloul a

a = dublu nou [n];

// citește din fișier în matrice și numere reale

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

// găsiți elementele maxime și minime

// în tabloul a și indicii acestora

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

dacă (a [i]> max)

max = a [i];

dacă (a [i]

min = a [i];

// in miscare indicator La maxim element

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

// scrie min în loc de elementul de fișier maxim

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

// in miscare indicator La minim element

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

// scrie max în loc de elementul de fișier minim

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

// închide fișierul

fclose (f);

// memorie libera

șterge [ ] A;

sistem („pauză”);

Etichete: Fișiere text, fopen, fclose, feof, setbuf, setvbuf, fflush, fgetc, fprintf, fscanf, fgets, flux în buffer, flux fără tampon.

Lucrul cu fișiere text

Lucrul cu un fișier text este similar cu lucrul cu o consolă: folosind funcții de intrare formatate, salvăm datele într-un fișier, folosind funcții de ieșire formatate, citim date dintr-un fișier. Sunt multe nuanțe pe care le vom analiza mai târziu. Principalele operațiuni care trebuie făcute sunt

  • 1. Deschideți fișierul, astfel încât să vă puteți referi la el. În consecință, este posibil să se deschidă pentru citire, scriere, citire și scriere, rescriere sau scriere până la sfârșitul fișierului etc. Când deschideți un fișier, pot apărea și o grămadă de erori - este posibil ca fișierul să nu existe, poate fi tipul greșit de fișier, este posibil să nu aveți permisiunea de a lucra la fișier etc. Toate acestea trebuie luate în considerare.
  • 2. Lucrul direct cu fișierul - scriere și citire. De asemenea, trebuie amintit aici că nu lucrăm cu memorie cu acces aleatoriu, ci cu un flux tamponat, care adaugă propriile sale specificități.
  • 3. Închideți fișierul. Deoarece fișierul este o resursă externă programului, dacă nu este închis, acesta va continua să rămână în memorie, eventual chiar și după ce programul este închis (de exemplu, nu va fi posibil să ștergeți un fișier deschis sau să faceți modificări, etc.). În plus, uneori este necesar să nu închideți, ci să „redeschideți” fișierul pentru, de exemplu, a schimba modul de acces.

În plus, există o serie de sarcini când nu avem nevoie să accesăm conținutul unui fișier: redenumire, mutare, copiere etc. Din păcate, standardul C nu oferă o descriere a funcțiilor pentru aceste nevoi. Ele sunt, desigur, disponibile pentru fiecare dintre implementările compilatorului. Citirea conținutului unui director (dosar, director) este și un acces la un fișier, deoarece un folder în sine este un fișier cu metainformații.

Uneori este necesar să efectuați unele operații auxiliare: mutați în locația dorită din fișier, amintiți-vă poziția curentă, determinați lungimea fișierului etc.

Un obiect FILE este necesar pentru a lucra cu un fișier. Acest obiect stochează ID-ul fluxului de fișiere și informațiile de care aveți nevoie pentru a-l manipula, inclusiv un pointer către buffer-ul său, un indicator de poziție a fișierului și indicatorii de stare.

Obiectul FILE este în sine o structură, dar câmpurile sale nu trebuie accesate. Un program portabil trebuie să trateze fișierul ca pe un obiect abstract care permite accesul la fluxul de fișiere.

Crearea și alocarea memoriei pentru un obiect de tip FILE se realizează folosind funcțiile fopen sau tmpfile (mai sunt altele, dar ne vom concentra doar pe acestea).

Funcția fopen deschide un fișier. Este nevoie de două argumente - un șir cu adresa fișierului și un șir cu modul de acces la fișier. Numele fișierului poate fi absolut sau relativ. fopen returnează un pointer către un obiect FILE care poate fi folosit pentru a accesa în continuare fișierul.

FILE * fopen (const char * nume de fișier, const char * mode);

De exemplu, să deschidem un fișier și să-i scriem Hello World

#include #include #include void main () (// Folosind variabila fișier vom accesa fișierul FILE * fișier; // Deschide un fișier text cu permisiuni de scriere fișier = fopen ("C: /c/test.txt", "w + t") ; // Scrieți în fișierul fprintf (fișier, „Bună ziua, lume!”); // Închideți fișierul fclose (fișier); getch ();)

Funcția fopen în sine alocă memorie pentru obiect, curățarea este efectuată de funcția fclose. Este obligatoriu să închideți dosarul, acesta nu se va închide singur.

Funcția fopen poate deschide un fișier în mod text sau binar. Valoarea implicită este text. Modul de acces poate fi după cum urmează

Parametrii de acces la fișiere.
Un fel Descriere
r Citind. Fișierul trebuie să existe.
w Scrierea unui nou fișier. Dacă un fișier cu același nume există deja, atunci conținutul acestuia se va pierde.
A Scrierea până la sfârșitul fișierului. Operațiunile de poziționare (fseek, fsetpos, frewind) sunt ignorate. Fișierul este creat dacă nu a existat.
r + Citirea și actualizarea. Poți să citești și să scrii. Fișierul trebuie să existe.
w + Înregistrare și actualizare. Este creat un nou fișier. Dacă un fișier cu același nume există deja, atunci conținutul acestuia se va pierde. Poți și să scrii și să citești.
un + Încheiați scrierea și actualizați. Operațiile de poziționare sunt doar în citire; sunt ignorate pentru scriere. Dacă fișierul nu a existat, va fi creat unul nou.

Dacă trebuie să deschideți un fișier în modul binar, atunci litera b este adăugată la sfârșitul liniei, de exemplu, „rb”, „wb”, „ab” sau, pentru modul mixt, „ab +”, „wb +”, „ab +”. În loc de b, puteți adăuga litera t, apoi fișierul se va deschide în modul text. Depinde de implementare. În noul standard C (2011), litera x înseamnă că funcția fopen ar trebui să eșueze dacă fișierul există deja. Să completăm vechiul nostru program: redeschidem fișierul și considerăm că am scris acolo.

#include #include #include void main () (FIȘIER * fișier; buffer de caractere; fișier = fopen ("C: /c/test.txt", "w"); fprintf (fișier, "Bună ziua, lume!"); fclose (fișier); fișier = fopen ("C: /c/test.txt", "r"); fgets (buffer, 127, fișier); printf ("% s", buffer); fclose (fișier); getch ();)

Ați fi putut folosi fscanf în loc de fgets, dar amintiți-vă că poate citi doar o linie până la primul spațiu.
fscanf (fișier, „% 127s”, buffer);

De asemenea, în loc să deschideți și să închideți fișierul, puteți utiliza funcția freopen, care „redeschide” fișierul cu noi permisiuni.

#include #include #include void main () (FIȘIER * fișier; buffer de caractere; fișier = fopen ("C: /c/test.txt", "w"); fprintf (fișier, "Bună ziua, lume!"); freopen ("C: / c / test.txt "," r ", fișier); fgets (buffer, 127, fișier); printf ("% s", buffer); fclose (fișier); getch ();)

Funcțiile fprintf și fscanf diferă de printf și scanf doar prin aceea că iau ca prim argument un pointer către un FIȘIER către care vor imprima sau din care vor citi date. Merită să adăugați aici imediat că funcțiile printf și scanf pot fi înlocuite fără probleme cu funcțiile fprintf și fscanf. În sistemul de operare (luăm în considerare cele mai comune și adecvate sisteme de operare), există trei fluxuri standard: standard output stdout, standard input stdin și standard error output stderr. Acestea sunt deschise automat în timpul pornirii aplicației și sunt asociate cu consola. Exemplu

#include #include #include void main () (int a, b; fprintf (stdout, „Introduceți două numere \ n”); fscanf (stdin, „% d”, & a); fscanf (stdin, „% d”, & b); dacă (b == 0) (fprintf (stderr, „Eroare: împărțire la zero”);) else (fprintf (stdout, „% .3f”, (float) a / (float) b);) getch ();)

Eroare de deschidere a fișierului

Dacă apelul la fopen eșuează, va returna NULL. Erorile în timpul lucrului cu fișiere sunt destul de frecvente, așa că de fiecare dată când deschidem un fișier, trebuie să verificăm rezultatul lucrării.

#include #include #include #define ERROR_OPEN_FILE -3 void main () (FIȘIER * fișier; buffer de caractere; fișier = fopen ("C: /c/test.txt", "w"); if (fișier == NULL) (printf ("Eroare de deschidere fișier "); getch (); ieșire (ERROR_OPEN_FILE);) fprintf (fișier, "Bună ziua, lume!"); freopen ("C: /c/test.txt "," r ", fișier); if (fișier = = NULL) (printf ("Eroare la deschiderea fișierului"); getch (); exit (ERROR_OPEN_FILE);) fgets (buffer, 127, fișier); printf ("% s", buffer); fclose (fișier); getch () ;)

Problema este cauzată de cazul în care mai multe fișiere sunt deschise simultan: dacă unul dintre ele nu poate fi deschis, atunci și restul trebuie închis.

FILE * inputFile, * outputFile; nesemnat m, n; nesemnat i, j; inputFile = fopen (INPUT_FILE, READ_ONLY); if (inputFile == NULL) (printf ("Eroare la deschiderea fișierului% s", INPUT_FILE); getch (); exit (3);) outputFile = fopen (OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) (printf ("Eroare la deschiderea fișierului% s", OUTPUT_FILE); getch (); if (inputFile! = NULL) (fclose (inputFile);) exit (4);) ...

În cazuri simple, puteți acționa direct, ca în fragmentul anterior de cod. În cazuri mai complexe, se folosesc metode care înlocuiesc RAII din C++: wrapper-uri sau caracteristici ale compilatorului (curățare în GCC), etc.

Memorarea datelor

După cum am menționat mai devreme, atunci când scoatem date, acestea sunt mai întâi puse într-un buffer. Buffer-ul este șters

  • 1) Dacă este plin
  • 2) Dacă fluxul este închis
  • 3) Dacă indicăm în mod explicit că este necesară ștergerea tamponului (există și excepții aici :)).
  • 4) De asemenea, șters dacă programul s-a încheiat cu succes. În același timp, toate fișierele sunt închise. Dacă există o eroare de rulare, aceasta poate să nu se întâmple.

Puteți forța descărcarea buffer-ului apelând funcția fflush (Fișier *). Să ne uităm la două exemple - cu și fără curățare.

#include #include #include void main () (FIȘIER * fișier; char c; fișier = fopen ("C: /c/test.txt", "w"); do (c = getch (); fprintf (fișier, "% c", c ); fprintf (stdout, "% c", c); // fflush (fișier);) while (c! = "q"); fclose (fișier); getch ();)

Anulați comentariul apelului fflush. În timpul execuției, deschideți un fișier text și observați comportamentul.

Puteți atribui personal un buffer de fișier setând propria dimensiune. Acest lucru se face folosind funcția

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

care ia un FILE deja deschis și un pointer către un nou buffer. Dimensiunea noului buffer nu trebuie să fie mai mică decât BUFSIZ (de exemplu, pe stația de lucru curentă, BUFSIZ este de 512 octeți). Dacă treceți NULL ca buffer, fluxul va deveni fără tampon. De asemenea, puteți utiliza funcția

Int setvbuf (FILE * stream, char * buffer, int mode, size_t size);

care ia un tampon de dimensiune arbitrară. Modul poate lua următoarele valori

  • _IOFBF- tamponare completă. Datele sunt scrise în fișier când este plin. La citire, tamponul este considerat plin atunci când este solicitată o operație de intrare și tamponul este gol.
  • _IOLBF- tamponare liniară. Datele sunt scrise în fișier atunci când este plin sau când este întâlnit un caracter newline. La citire, tamponul este umplut până la un caracter de nouă linie atunci când este solicitată o operație de introducere și tamponul este gol.
  • _IONBF- fără tamponare. În acest caz, parametrii dimensiune și buffer sunt ignorați.
Dacă are succes, funcția returnează 0.

Exemplu: să ne setăm propriul buffer și să vedem cum se efectuează citirea dintr-un fișier. Fișierul să fie scurt (ceva de genul Hello, World!), Și îl citim caracter cu caracter

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

Puteți vedea că datele sunt deja în buffer. Citirea caracter cu caracter este deja efectuată din buffer.

feof

Funcția int feof (FILE * stream); returnează adevărat dacă a fost atins sfârșitul fișierului. Această funcție este utilă atunci când trebuie să parcurgeți întregul fișier de la început până la sfârșit. Să existe un fișier cu conținut text text.txt. Citim fișierul caracter cu caracter și îl afișăm pe ecran.

#include #include #include void main () (FILE * input = NULL; char c; input = fopen ("D: /c/text.txt", "rt"); if (input == NULL) (printf ("Eroare la deschiderea fișierului") ; _getch (); exit (0);) while (! feof (input)) (c = fgetc (input); fprintf (stdout, "% c", c);) fclose (input); _getch ();)

Totul ar fi bine, doar că funcția feof nu funcționează corect... Acest lucru se datorează faptului că conceptul de „sfârșit de fișier” nu este definit. Când se utilizează feof, apare adesea o eroare când ultimele date citite sunt scoase de două ori. Acest lucru se datorează faptului că datele sunt scrise în bufferul de intrare, ultima citire are loc cu o eroare și funcția returnează vechea valoare citită.

#include #include #include void main () (FILE * input = NULL; char c; input = fopen ("D: /c/text.txt", "rt"); if (input == NULL) (printf ("Eroare la deschiderea fișierului") ; _getch (); exit (0);) while (! feof (input)) (fscanf (input, "% c", & c); fprintf (stdout, "% c", c);) fclose (input) ; _getch ();)

Acest exemplu va eșua (cel mai probabil) și va scoate ultimul caracter al fișierului de două ori.

Soluția este să nu folosești feof. De exemplu, stocați numărul total de înregistrări sau profitați de faptul că fscanf etc. returnează de obicei numărul de valori citite corect și potrivite.

#include #include #include void main () (FILE * input = NULL; char c; input = fopen ("D: /c/text.txt", "rt"); if (input == NULL) (printf ("Eroare la deschiderea fișierului") ; _getch (); ieșire (0);) while (fscanf (intrare, „% c”, & c) == 1) (fprintf (stdout, „% c”, c);) fclose (intrare); _getch ( ) ;)

Exemple de

1. Două numere sunt scrise într-un fișier - dimensiunile matricei. Să umplem al doilea fișier cu o serie de numere aleatorii.

#include #include #include #include // Numele și permisiunile fișierelor #define INPUT_FILE "D: /c/input.txt" #define OUTPUT_FILE "D: /c/output.txt" #define READ_ONLY "r" #define WRITE_ONLY "w" // Valoarea maximă pentru matrice dimensiune #define MAX_DIMENSION 100 // Eroare la deschiderea fișierului #define ERROR_OPEN_FILE -3 void main () (FILE * inputFile, * outputFile; unsigned m, n; unsigned i, j; inputFile = fopen (INPUT_FILE, READ_ONLY); if ( inputFile = = NULL) (printf ("Eroare la deschiderea fișierului% s", INPUT_FILE); getch (); ieșire (ERROR_OPEN_FILE);) outputFile = fopen (OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) (printf ("Eroare la deschiderea fișierului) % s ", OUTPUT_FILE); getch (); // Dacă fișierul a fost deschis pentru citire, atunci trebuie închis dacă (inputFile! = NULL) (fclose (inputFile);) exit (ERROR_OPEN_FILE);) fscanf (inputFile, „% ud% ud”, & m, & n); dacă (m> MAX_DIMENSION) (m = MAX_DIMENSION;) dacă (n> MAX_DIMENSION) (n = MAX_DIMENSION;) srand (timp (NULL)); pentru (i = 0; i< n; i++) { for (j = 0; j < m; j++) { fprintf(outputFile, "%8d ", rand()); } fprintf(outputFile, "\n"); } //Закрываем файлы fclose(inputFile); fclose(outputFile); }

2. Utilizatorul copiază fișierul și mai întâi selectează modul de operare: fișierul poate fi scos atât în ​​consolă, cât și copiat într-un fișier nou.

#include #include #include #define ERROR_FILE_OPEN -3 void main () (FILE * origine = NULL; FILE * output = NULL; char nume de fișier; mod int; printf ("Introduceți numele fișierului:"); scanf ("% 1023s", nume fișier); origin = fopen (nume fișier, "r"); if (origine == NULL) (printf ("Eroare la deschiderea fișierului% s", nume fișier); getch (); ieșire (ERROR_FILE_OPEN);) printf ("introduceți modul:"); scanf ( "% d", & mode); if (mod == 1) (printf ("Introduceți numele fișierului:"); scanf ("% 1023s", nume fișier); output = fopen (nume fișier, "w"); if (ieșire = = NULL) (printf ("Eroare la deschiderea fișierului% s", nume fișier); getch (); fclose (origine); exit (ERROR_FILE_OPEN);)) else (ieșire = stdout;) while (! Feof (origine)) ( fprintf (ieșire, „% c”, fgetc (origine));) fclose (origine); fclose (ieșire); getch ();)

3. Utilizatorul introduce date din consolă și acestea sunt scrise în fișier până când tasta esc este apăsată. Verificați programul și vedeți. cum se comportă dacă tastați backspace: ce este scos la un fișier și ce este scos la consolă.

#include #include #include #define ERROR_FILE_OPEN -3 void main () (FILE * output = NULL; char c; output = fopen ("D: /c/test_output.txt", "w + t"); if (ieșire == NULL) (printf ("Eroare la deschiderea fișierului"); _getch (); ieșire (ERROR_FILE_OPEN);) pentru (;;) (c = _getch (); if (c == 27) (break;) fputc (c, ieșire); fputc ( c, stdout);) fclose (ieșire);)

4. Fișierul conține numere întregi. Găsiți maximul dintre ele. Să profităm de faptul că funcția fscanf returnează numărul de obiecte citite și potrivite corect. Numărul 1 ar trebui returnat de fiecare dată.

#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 ("Eroare la deschiderea fișierului"); _getch (); ieșire (ERROR_FILE_OPEN);) maxn = INT_MIN; hasRead = 1; while (hasRead == 1) (hasRead = fscanf (input, "% d", & num) ; dacă (areRead! = 1) (continuare;) dacă (num>

O altă soluție este să citim numerele până ajungem la sfârșitul fișierului.

#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 ("Eroare la deschiderea fișierului"); _getch (); ieșire (ERROR_FILE_OPEN);) maxn = INT_MIN; while (! feof (intrare)) (fscanf (input, "% d", & num); if (num> maxn ) (maxn = num;)) printf ("număr maxim =% d", maxn); fclose (input); _getch ();)

5. Fișierul conține cuvinte: cuvânt rusesc, tabulare, cuvânt englezesc, pe mai multe rânduri. Utilizatorul introduce un cuvânt englezesc, este necesar să-l afișeze pe cel rusesc.

Fișierul de traducere arată cam așa

soare soare
pix creion
creion stilou
usa usa
fereastra windows
scaun scaun
fotoliu scaun

și salvat în codificare cp866 (OEM 866). Este important ca ultima pereche de cuvinte să se încheie și cu un avans de linie.

Algoritmul este următorul - citim linia din fișier, găsim semnul de tabulare în linie, înlocuim semnul de tabulare cu zero, copiam cuvântul rus din buffer, copiem cuvântul englez din buffer, verificăm egalitatea.

#include #include #include #include #define ERROR_FILE_OPEN -3 void main () (FILE * input = NULL; char buffer; char enWord; char ruWord; char usrWord; unsigned index; int length; int wasFound; input = fopen ("D: /c/input.txt "," r "); if (input == NULL) (printf (" Eroare la deschiderea fișierului "); _getch (); exit (ERROR_FILE_OPEN);) printf (" introduceți cuvântul: "); fgets (usrWord, 127, stdin ); wasFound = 0; while (! feof (input)) (fgets (buffer, 511, input); length = strlen (buffer); 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. Numărați numărul de linii din fișier. Să citim fișierul caracter cu caracter, numărând numărul de caractere „\ n” până când găsim caracterul EOF. EOF este un caracter special care indică faptul că intrarea este completă și că nu mai sunt date de citit. Funcția returnează o valoare negativă în caz de eroare.
NOTĂ: EOF este int, deci trebuie să utilizați int pentru a citi caracterele. În plus, valoarea EOF nu este definită de standard.

#define _CRT_SECURE_NO_WARNINGS #include #include #include int cntLines (const char * nume de fișier) (int lines = 0; int orice; // orice de tip int, deoarece EOF este de tip int! FILE * f = fopen (nume fișier, "r"); if (f == NULL ) (întoarce -1;) do (orice = fgetc (f); // printf ("% c", orice); // depanare dacă (oricare == "\ n") (linii ++;)) while ( orice! = EOF); ​​​​fclose (f); return lines;) void main () (printf ("% d \ n", cntLines ("C: /c/file.txt")); _getch (); )

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

Încă nu este clar? - scrieți întrebări în căsuța poștală

Top articole similare