C citirea și scrierea într-un fișier text. Lucrul cu fișiere text

Ultima actualizare: 31.10.2015

Clasă FileStream reprezintă capacitățile de a citi dintr-un fișier și de a scrie într-un fișier. Vă permite să lucrați atât cu fișiere text, cât și cu cele binare.

Să luăm în considerare cele mai importante proprietăți și metode ale sale:

    Proprietatea Length: returnează lungimea fluxului în octeți

    Proprietatea poziției: returnează poziția curentă în flux

    Metoda de citire: citește datele dintr-un fișier într-o matrice de octeți. Preia trei parametri: int Read(byte array, int offset, int count) și returnează numărul de octeți citiți cu succes. Următorii parametri sunt utilizați aici:

    • matrice - o matrice de octeți în care vor fi plasate datele citite din fișier

      offset reprezintă offset-ul în octeți în matrice, în care vor fi plasați octeții citiți

      count - numărul maxim de octeți care trebuie citiți. Dacă există mai puțini octeți în fișier, atunci toți vor fi citiți.

    Metodă long Seek (offset lung, origine SeekOrigin): setează poziția în flux cu un offset cu numărul de octeți specificat în parametrul offset.

    Metoda de scriere: scrie date dintr-o matrice de octeți într-un fișier. Ia trei parametri: Write (byte array, int offset, int count)

    • matrice - o matrice de octeți din care datele vor fi scrise în fișier

      offset - offset-ul în octeți din matricea de unde încep să se scrie octeții în flux

      count - numărul maxim de octeți de scris

FileStream reprezintă accesul la fișier la nivel de octet, deci, de exemplu, dacă trebuie să citiți sau să scrieți una sau mai multe linii într-un fișier text, atunci matricea de octeți trebuie convertită în șiruri de caractere folosind metode speciale. Prin urmare, alte clase sunt folosite pentru a lucra cu fișiere text.

În același timp, atunci când lucrați cu diferite fișiere binare care au o anumită structură, FileStream poate fi foarte util pentru extragerea anumitor informații și procesarea acestora.

Să ne uităm la un exemplu de citire și scriere într-un fișier text:

Console.WriteLine("Introduceți o linie pentru a scrie în fișier:"); string text = Console.ReadLine(); // scrierea într-un fișier utilizând (FileStream fstream = new FileStream(@"C:\SomeDir\noname\note.txt", FileMode.OpenOrCreate)) ( // convertiți șirul în bytes byte array = System.Text.Encoding. Implicit. GetBytes(text) // scrierea unei matrice de octeți într-un fișier fstream.Write(array, 0, array.Length("Text scris în fișier"); fstream = Fișier OpenRead(@"C:\SomeDir\noname\note.txt")) ( // convertește șirul în octeți matrice de octeți = octet nou; // citește datele fstream.Read(array, 0, array. Lungime); // decodează octeți în șirul textFromFile = System.Text.Encoding.Default.GetString(array.WriteLine("Text din fișier: (0)", textFromFile ) Console.ReadLine();

Să ne uităm la acest exemplu. Atât citirea cât și scrierea folosesc declarația using. Nu fi confuz acest operator cu o directivă using care include spații de nume la începutul fișierului de cod. Instrucțiunea using vă permite să creați un obiect într-un bloc de cod, după finalizarea căruia este apelată metoda Dispose a acelui obiect și astfel obiectul este distrus. În acest caz, variabila fstream servește ca un astfel de obiect.

Obiectul fstream este creat de doi căi diferite: prin constructor si prin unul dintre metode statice Class File.

Aici doi parametri sunt trecuți constructorului: calea fișierului și enumerarea FileMode. Această enumerare indică modul de acces la fișier și poate lua următoarele valori:

    Adăugați: dacă fișierul există, textul este atașat la sfârșitul fișierului. Dacă fișierul nu există, acesta este creat. Fișierul este deschis doar pentru scriere.

    Creare: creat fișier nou. Dacă un astfel de fișier există deja, acesta este suprascris

    CreateNew: este creat un nou fișier. Dacă un astfel de fișier există deja, atunci aplicația aruncă o eroare

    Deschide: Deschide un fișier. Dacă fișierul nu există, se aruncă o excepție

    OpenOrCreate : dacă fișierul există, acesta este deschis, dacă nu, se creează unul nou

    Trunchiați: dacă fișierul există, acesta este suprascris. Fișierul este deschis doar pentru scriere.

Metoda statică OpenRead a clasei File deschide un fișier pentru citire și returnează un obiect FileStream.

Constructor clasa FileStream are, de asemenea, o serie de supraîncărcări permițând o personalizare mai precisă obiect creat. Toate aceste versiuni pot fi vizualizate pe msdn.

Atât scrierea, cât și citirea folosesc obiectul de codificare Encoding.Default din spațiul de nume System.Text. În acest caz, folosim două dintre metodele sale: GetBytes pentru a obține o matrice de octeți dintr-un șir și GetString pentru a obține un șir dintr-o matrice de octeți.

Drept urmare, șirul pe care l-am introdus este scris în fișier notă.txt. În esență, acesta este un fișier binar (nu un fișier text), deși dacă scriem doar o linie în el, putem vizualiza acest fișier într-o formă care poate fi citită de om, deschizându-l într-un editor de text. Cu toate acestea, dacă scriem octeți aleatori în el, de exemplu:

Fstream.WriteByte(13); fstream.WriteByte(103);

Atunci s-ar putea să avem probleme în a înțelege. Prin urmare, clasele separate sunt concepute pentru a funcționa direct cu fișiere text - StreamReader și StreamWriter.

Acces aleatoriu la fișiere

De multe ori fișiere binare reprezintă o anumită structură. Și, cunoscând această structură, putem lua informația necesară din fișier sau, dimpotrivă, o putem scrie în anumit loc fișier un anumit set de octeți. De exemplu, în fișierele wav, datele audio în sine încep de la 44 de octeți, iar până la 44 de octeți există diverse metadate - numărul de canale audio, frecvența de eșantionare etc.

Folosind metoda Seek() putem controla poziția cursorului de flux, pornind de la care este citit sau scris fișierul. Această metodă ia doi parametri: offset și poziția în fișier. O poziție într-un fișier este descrisă de trei valori:

    SeekOrigin.Begin : începutul fișierului

    SeekOrigin.End : sfârșitul fișierului

    SeekOrigin.Current : poziția curentă în fișier

Cursorul fluxului de la care începe citirea sau scrierea este deplasat înainte prin offset față de poziția specificată ca al doilea parametru. Offset-ul poate fi negativ, apoi cursorul se deplasează înapoi, dacă este pozitiv, apoi înainte.

Să ne uităm la un exemplu:

Folosind System.IO; folosind System.Text; clasa Program ( static void Main(string args) ( string text = " Salut Lume"; // scrierea într-un fișier folosind (FileStream fstream = new FileStream(@"D:\note.dat", FileMode.OpenOrCreate)) ( // convertiți șirul în bytes byte input = Encoding.Default.GetBytes(text) ; // scrierea unui array de octeți în fișierul fstream.Write(input, 0, input.Length("Text scris în fișier"); până la sfârșitul fișierului fstream.Seek(- 5, SeekOrigin.End // minus 5 caractere de la sfârșitul fluxului // citește patru caractere din poziția curentă byte output = new byte(output, 0, output). Length); // decodează octeții într-un șir textFromFile = Encoding.Default.GetString(output Console.WriteLine("Text din fișier: (0)", textFromFile // înlocuiți cuvântul); cuvântul house șir replaceText = "house" (-5, SeekOrigin.End) // minus 5 caractere de la sfârșitul fluxului de intrare = Encoding.Default.GetBytes(replaceText.Write(input, 0, input); .Length); // citește întregul fișier // returnează indicatorul la începutul fișierului fstream.Seek(0, SeekOrigin.Begin); ieșire = octet nou; fstream.Read(ieșire, 0, ieșire.Lungime); // decodifică octeții într-un șir textFromFile = Encoding.Default.GetString(output); Console.WriteLine("Text din fișier: (0)", textFromFile); // salut casa ) Console.Read(); ) )

Ieșire din consolă:

Text scris în fișier Text din fișier: worl Text din fișier: salut casă

Apelarea fstream.Seek(-5, SeekOrigin.End) mută cursorul fluxului la sfârșitul fișierelor înapoi cu cinci caractere:

Adică, după ce ați scris linia „hello world” într-un fișier nou, cursorul se va afla în poziția caracterului „w”.

După aceasta, citim patru octeți care încep cu caracterul „w”. În această codificare, 1 caracter va reprezenta 1 octet. Prin urmare, citirea a 4 octeți va echivala cu citirea a patru caractere: „lumea”.

Apoi, din nou, trecem la sfârșitul fișierului, fără a ajunge la sfârșitul a cinci caractere (adică din nou din poziția caracterului „w”) și scriem șirul „casa”. Deci șirul „casa” înlocuiește șirul „lume”.

Închiderea unui fir

În exemplele de mai sus, o construcție de utilizare este utilizată pentru a închide un flux. După ce toate instrucțiunile și expresiile din blocul de utilizare au fost procesate, obiectul FileStream este distrus. Cu toate acestea, putem alege o altă cale:

FileStream fstream = nul; încercați ( fstream = new FileStream(@"D:\note3.dat", FileMode.OpenOrCreate); // operațiuni cu fluxul ) catch(Exception ex) ( ) finally ( if (fstream != null) fstream.Close() ;

Dacă nu folosim constructul using, atunci avem nevoie explicit apelați metoda Close(): fstream.Close()

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 fi nevoie să le introducă de la tastatură.

    Text sunt apelate fișiere formate din orice caractere. Ele sunt organizate în rânduri, fiecare 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.

    ÎN binarÎn 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 este folosit 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, se folosește un flux 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, aveți nevoie de:

    descrie o variabilă de tip de flux.

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

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

Pentru citind date dintr-un fișier text, aveți nevoie de:

    descrie o variabilă de tip ifstream.

    deschideți un fișier folosind funcția de deschidere.

    închideți fișierul.

Record informații într-un fișier text

    După cum am menționat mai devreme, pentru a începe lucrul cu fisier text, trebuie descris variabila de tip ofstream. De exemplu, așa:

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

    În etapa următoare, fișierul trebuie deschis 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,

fisier - Numele complet fișier pe disc

mod - modul de lucru cu fișierul deschis.

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

D:\\joc\\noobs.txt.

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

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

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

ios::app - deschideți fișierul î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, asta se întâmplă și în modul ios::out;

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

ios::noreplace - nu deschide fișier existent.

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

După deschiderea cu succes a fișierului (în orice mod), variabila F va stoca true, în caz contrar false. Acest lucru vă va permite să verificați corectitudinea operațiunii de deschidere a fișierului.

Puteți deschide un fișier (să luăm ca exemplu fișierul D:\\game\\noobs.txt) în modul înregistrare în unul dintre următoarele moduri:

// primul cale

din fluxul F;

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

//a doua metodă, modul ios::out este modul implicit

// Pentru curgereofstream

din fluxul F;

//a treia metodă combină descrierea variabilei și tipul fluxului

//și deschiderea fișierului într-o singură instrucțiune

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

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

Dacă doriți să deschideți un fișier existent în modul de scriere mai întâi, ar trebui să utilizați ios::app ca mod.

După deschiderea unui fișier în modul de înregistrare, 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, instrucțiunea 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 astfel:

G<

Închiderea unui flux se face folosind operatorul:

EXEMPLU:

Creați un fișier text D:\\game\\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:\\game\\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<

//închiderea fluxului

f.close();

sistem(„pauză”);

returnează 0;

_______________________________________________________________

Pentru a citi informații dintr-un fișier text, trebuie să descrii o variabilă precum ifstream. După aceasta, trebuie să deschideți fișierul pentru citire folosind operatorul deschis. Dacă variabila se numește F, atunci primele două afirmații vor fi astfel:

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

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, tab, sfârșit de rând. Este bine dacă programatorul știe dinainte câte și ce valori să stocheze în fișierul text. Cu toate acestea, adesea tipul de valori stocate în fișier este pur și simplu cunoscut, dar numărul acestora poate varia. Pentru a rezolva 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. Există o funcție pentru asta F. eof().

Aici F este numele firului de execuție, funcția returnează o valoare booleană: adevărat sau fals, în funcție de sfârșitul fișierului. Prin urmare, o buclă pentru a citi conținutul întregului fișier poate fi scrisă astfel:

//organizare pentru citirea valorilor dintr-un fișier, execuție

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

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

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

EXEMPLU:

Fișierul text D:\\game\\noobs.txt stochează numere reale, le afișează pe ecran și le calculează numărul.

#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 de 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 buclei 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())

//citirea următoarei valori din fluxul F în variabila a

F>>a;

//trimite valoarea variabilei a pe ecran

cout<

//crește numărul de numere citite

//închiderea fluxului

F.close();

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

cout<<"n="<

//dacă deschiderea fișierului a fost incorectă, atunci rezultatul

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

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

sistem(„pauză”);

returnează 0;

C++. Procesarea 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 operatorul FILE *filename; Aici filename este numele variabilei în care va fi stocat indicatorul către fișier.

    scrieți informații într-un fișier folosind funcția fwrite

Pentru a considera b date dintr-un fișier binar, aveți nevoie de:

    descrie o variabilă de tip FILE *

    deschideți un fișier folosind funcția fopen

    închideți un fișier folosind funcția fclose

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

Pentru descoperiri Fișierul este destinat funcției fopen.

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

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

„rb” - deschideți fișierul binar în modul de citire;

„wb” - creați un fișier binar pentru înregistrare; dacă există, 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-scriere;

„wb+” - deschideți fișierul 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 de fișier f dacă fișierul se deschide fără succes. După deschiderea unui fișier, al 0-lea octet al acestuia este disponibil, indicatorul fișierului este 0, a cărui valoare, pe măsură ce este citit sau scris, este deplasată cu numărul de octeți citiți (scriși). Valoarea curentă a indicatorului de fișier este numărul de octeți de la care va avea loc operația de citire sau scriere.

Pentru închidere fișierul este destinat funcției fclose

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

Returnează 0 dacă fișierul a fost închis cu succes, NULL în caz contrar.

Funcția de eliminare este pentru îndepărtare fişiere.

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

Această funcție șterge de pe disc un fișier numit fileenema. Fișierul de șters trebuie să fie închis. Funcția returnează o valoare 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 numele vechiului fișier, al doilea este cel nou. Returnează 0 dacă programul se încheie cu 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 dintr-un fișier, indicatorul acestuia este deplasat cu n*size octeți.

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

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

Funcția fwrite scrie în fișier nume de fișier dintr-o matrice ptr de n elemente cu dimensiunea mărimii. Funcția returnează numărul de elemente scrise. După scrierea informațiilor în fișier, indicatorul este deplasat cu n*size octeți.

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

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

Returnează o valoare diferită de zero dacă se ajunge la sfârșitul fișierului.

EXEMPLU:

Creați un fișier binar D:\\game\\noobs.dat și scrieți n numere întregi și n numere reale în el.

#include „stdafx.h”

#include

folosind namespace std;

int main()

setlocale(LC_ALL, "RUS");

int n, i;

dublu a;

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

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

// intrare numeren

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

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

//buclă pentru a introduce n numere reale

pentru (i=0; i

//introduceți următorul număr real

cout<<"a=";

cin>>a;

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

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

// închide fişier

fclose(f);

sistem(„pauză”);

returnează 0;

EXEMPLU:

Afișați conținutul fișierului binar D:\\game\\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ți variabila fișier

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

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

//ieșire 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

//Ieșiți 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 unui fisier, primul octet stocat in acesta este disponibil. Puteți scrie sau citi date dintr-un fișier secvenţial. Să presupunem că trebuie să numărați al cincisprezecelea număr și apoi primul. Folosind accesul secvenţial, acest lucru se poate face în felul următor:

int n, i;

dublu a;

DOSAR *f;

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

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

fclose(f);

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

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

fclose(f);

După cum puteți vedea, citirea numerelor dintr-un fișier și apoi deschiderea din nou a fișierului nu este cea mai convenabilă modalitate. Va fi 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 de poziție a fișierului curent F în conformitate cu valorile de origine și offset. Parametrul offset este egal cu numărul de octeți cu care indicatorul fișierului va fi decalat în raport cu originea specificată de parametrul origine. Valoarea parametrului de origine trebuie să fie una dintre următoarele valori de offset 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ă o valoare zero dacă operația a avut succes, diferită de zero dacă offset-ul a eșuat.

Funcția fseek implementează de fapt accesul direct la orice valoare dintr-un 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 fișierele binare folosind următoarea problemă ca exemplu.

EXEMPLU

În fișierul binar D:\\game\\noobs.dat creat mai devreme, schimbați cele mai mari și cele mai mici numere reale.

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

    citirea reale dintr-un fișier în matrice a.

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

    mutarea indicatorului de fișier la valoarea maximă și scrierea min.

    mutarea indicatorului de fișier la valoarea minimă și scrierea 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 un fișier în modul citire-scriere

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

//citește numărul din fișier în variabila n

//numerele reale din fișier

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

cout<<"n="<

//aloca 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(double), n, f);

//căutați elemente 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 elementul minim în loc de maxim

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

// in miscare indicator La minim element

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

//Înregistrează max în loc de elementul de fișier minim

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

//închiderea fișierului

fclose(f);

//memorie libera

șterge [ ]A;

sistem(„pauză”);

Pentru a facilita accesul, informațiile din dispozitivele de stocare sunt stocate sub formă de fișiere.

Un fișier este o zonă denumită a memoriei externe alocată pentru stocarea unei matrice de date. Datele conținute în fișiere sunt de natură foarte diversă: programe în limbaj algoritmic sau mașină; date inițiale pentru funcționarea programului sau rezultatele execuției programului; texte libere; 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, utilizate în sistemul de fișiere pentru a simplifica organizarea fișierelor.

Sistemul de fișiere numită partea funcțională a sistemului de operare care efectuează operațiuni asupra fișierelor. 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 a stoca numărul clusterului. FAT12 este folosit în principal pentru dischete (până la 4 KB), FAT16 – pentru discuri de capacitate mică, FAT32 – pentru unități FLASH de mare capacitate (până la 32 GB).

Să ne uităm la structura sistemului de fișiere folosind FAT32 ca exemplu.

Structura fișierului FAT32

Dispozitivele de memorie externă din sistemul FAT32 au mai degrabă adresare bloc decât adresare octet. Informațiile sunt scrise pe un dispozitiv de memorie extern în blocuri sau sectoare.

Un sector este unitatea minimă 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 scrierea fișierelor sunt numerotate începând de la 2. De regulă, clusterul nr. 2 este folosit de directorul rădăcină, iar începând de la clusterul nr. 3 se stochează matricea de date. Sectoarele utilizate pentru stocarea informațiilor deasupra directorului rădăcină nu sunt grupate.
Dimensiunea minimă de fișier necesară pe disc corespunde unui cluster.

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

  • EB 58 90 – săritură necondiționată și semnătură;
  • 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 de cluster al directorului rădăcină;
  • 0x47 (11 octeți) – etichetă de volum;
  • 0x1FE (2 octeți) – semnătura sectorului de pornire (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ă necunoscut;
  • 0x1EC (4 octeți) – numărul ultimului cluster înregistrat;
  • 0x1FE (2 octeți) – semnătură (55 AA).

Tabelul FAT conține informații despre starea fiecărui cluster de pe disc. Cei 2 octeți inferiori ai tabelului FAT stochează F8 FF FF 0F FF FF FF FF FF (care corespunde stării clusterelor 0 și 1, care lipsesc fizic). În continuare, 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 despre fiecare fișier, care conține următoarele informații:

Când lucrați cu nume lungi de fișiere (inclusiv nume rusești), numele fișierului este codificat folosind sistemul de codare UTF-16. În acest caz, 2 octeți sunt alocați pentru codificarea fiecărui caracter. În acest caz, numele fișierului este scris în următoarea structură:

  • 1 octet secvență;
  • 10 octeți conțin cele 5 caractere inferioare ale numelui fișierului;
  • atribut de 1 octet;
  • 1 octet rezervat;
  • 1 octet – suma de control al numelui DOS;
  • 12 octeți conțin cele 3 caractere inferioare ale numelui fișierului;
  • 2 octeți – numărul primului cluster;
  • caracterele rămase ale numelui lung.

Lucrul cu fișiere în limbaj C

Pentru programator, un fișier deschis este reprezentat ca o secvență de date citite sau scrise. Când un fișier este deschis, acesta este asociat cu Fluxul 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 este asociat cu o structură FILE standard, care este definită în stdio.h. Structura FILE conține informațiile necesare despre fișier.

Deschiderea unui fișier se face folosind funcția fopen(), care returnează un pointer către o structură de tip FILE care poate fi folosită pentru operațiunile ulterioare asupra fișierului.

FIȘIER *fopen(nume, tip);


nume – numele fișierului de deschis (inclusiv calea),
type este un pointer către un șir de caractere care definește modul în care este accesat fișierul:
  • "r" - deschideți fișierul pentru citire (fișierul trebuie să existe);
  • "w" - deschideți un fișier gol pentru scriere; dacă fișierul există, conținutul acestuia se pierde;
  • "a" - deschideți fișierul pentru scriere până la sfârșit (pentru anexare); fisierul este creat daca nu exista;
  • "r+" - deschideți fișierul pentru citire și scriere (fișierul trebuie să existe);
  • "w+" - deschideți un fișier gol pentru citire și scriere; dacă fișierul există, conținutul acestuia se pierde;
  • „a+” - deschideți fișierul pentru citire și adăugare dacă fișierul nu există, atunci acesta 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 folosind funcția 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;
numele caracterului = "my.txt" ;
if ((fp = fopen(nume, "r" )) == NULL )
{
printf( "Deschiderea fișierului a eșuat");
getchar();
returnează 0;
}
// am reușit să deschid fișierul
... // acțiuni necesare asupra datelor
fclose(fp);
getchar();
returnează 0;
}

Citirea unui caracter dintr-un fișier:

char fgetc(stream);


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 simbol într-un fișier:

fputc(char, stream);

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 cu funcțiile scanf() și printf(), dar funcționează cu fișiere de date și au un pointer de fișier ca prim argument.

fscanf(stream, "InputFormat", argumente);

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

Lucrul cu fișiere text

Lucrul cu un fișier text este similar cu lucrul cu consola: folosind funcții de intrare formatate salvăm datele într-un fișier, folosind funcții de ieșire formatate citim datele 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 pentru a putea fi accesat. În consecință, îl puteți deschide 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 de fișier greșit, este posibil să nu aveți permisiunea de a lucra cu fișierul etc. Toate acestea trebuie luate în considerare.
  • 2. Lucrul direct cu fișierul - scriere și citire. Aici trebuie să ne amintim, de asemenea, 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” un fișier 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 fișierului: redenumire, mutare, copiere etc. Din păcate, standardul C nu conține 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) înseamnă și accesarea unui fișier, deoarece folderul î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.

Pentru a lucra cu un fișier, aveți nevoie de un obiect FILE. Acest obiect stochează identificatorul fluxului de fișiere și informațiile necesare pentru a-l gestiona, 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. Programul 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ția fopen sau tmpfile (mai sunt altele, dar ne vom concentra doar pe acestea).

Funcția fopen deschide un fișier. Primește 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, mod const char*);

De exemplu, să deschidem un fișier și să scriem Hello World în el

#include #include #include void main() ( //Folosind variabila fișier vom accesa fișierul FILE *file; //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!" //Închideți fișierul fclose(fișier);

Funcția fopen în sine alocă memorie pentru obiect; curățarea este efectuată de funcția fclose. Este necesar să închideți fișierul; 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ă

Opțiuni de acces la fișiere.
Tip Descriere
r Citind. Fișierul trebuie să existe.
w Scrieți un fișier nou. Dacă un fișier cu același nume există deja, conținutul acestuia se va pierde.
A Scrieți 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, conținutul acestuia se va pierde. Poți și să scrii și să citești.
a+ Încheiați postarea și actualizați. Operațiile de poziționare sunt doar în citire și ignorate pentru scrieri. Dacă fișierul nu a existat, va fi creat unul nou.

Dacă este necesar să deschideți fișierul î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ă fopen ar trebui să eșueze dacă fișierul există deja. Să completăm vechiul nostru program: redeschidem fișierul și luăm în considerare ce am scris acolo.

#include #include #include void main() ( FILE *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"(buffer, 127, file);

În loc de funcția fgets, puteți folosi fscanf, dar trebuie să vă amintiți că poate citi doar linia până la primul spațiu.
fscanf(fișier, „%127s”, buffer);

De asemenea, în loc să deschideți și să închideți un fișier, puteți utiliza funcția freeopen, care „redeschide” fișierul cu noi drepturi de acces.

#include #include #include void main() ( FILE *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 FIȘIERUL către care vor ieși sau din care vor citi date. Merită să adăugați imediat că funcțiile printf și scanf pot fi înlocuite cu ușurință de 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: flux de ieșire standard stdout, flux de intrare standard stdin și flux de ieșire de eroare standard stderr. Acestea sunt deschise automat la lansarea 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 la deschiderea fișierului

Dacă apelul funcției fopen eșuează, va returna NULL. Erori în timpul lucrului cu fișiere apar destul de des, 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() ( FILE *fișier; buffer de caractere; fișier = fopen("C:/c/test.txt", "w"); if (fișier == NULL) ( printf("Eroare la deschidere fișier"); getch(); ieșire (ERROR_OPEN_FILE); ) fprintf(fișier, "Bună ziua, lume!"); freopen ("C:/c/test.txt", "r", fișier); dacă (fișier = = NULL) ( printf("Eroare la deschiderea fișierului"); getch(); exit(ERROR_OPEN_FILE); ) fgets(buffer, 127, fișier); printf("%s", buffer(fișier); )

Problema apare atunci când se deschid mai multe fișiere 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, sunt folosite metode care înlocuiesc RAII din C++: wrapper-uri sau caracteristici ale compilatorului (curățare în GCC), etc.

Buffering de date

După cum am menționat mai devreme, atunci când scoatem date, acestea sunt mai întâi plasate î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 finalizat cu succes. În același timp, toate fișierele sunt închise. În cazul unei erori de rulare, aceasta poate să nu se întâmple.

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

#include #include #include void main() ( FILE *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)(c != "q");

Anulați comentariul apelului fflush. În timpul execuției, deschideți fișierul text și uitați-vă la comportament.

Puteți atribui singur 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 devine nebuffer. De asemenea, puteți utiliza funcția

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

care acceptă un buffer 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 caracterul 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)

Se poate observa că datele sunt deja în buffer. Citirea caracter cu caracter se face din buffer.

feof

Funcția int feof(FILE * stream); returnează true dacă se ajunge la sfârșitul fișierului. Funcția este convenabilă de utilizat 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());

Totul ar fi bine, dar funcția feof nu funcționează corect... Acest lucru se datorează faptului că conceptul de „sfârșit de fișier” nu este definit. O eroare care apare adesea la utilizarea feof este că ultimele date citite sunt tipărite de două ori. Acest lucru se datorează faptului că datele sunt scrise în buffer-ul 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); ();

Acest exemplu va eșua (cel mai probabil) și va imprima 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 utilizați faptul că funcțiile fscanf etc. returnează de obicei numărul de valori citite și potrivite corect.

#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);

Exemple

1. Un fișier conține două numere - 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); dacă ( inputFile == NULL) ( printf("Eroare la deschiderea fișierului %s", INPUT_FILE); getch(); exit(ERROR_OPEN_FILE); ) outputFile = fopen(OUTPUT_FILE, WRITE_ONLY if (outputFile == NULL) ( printf("Eroare); deschiderea fișierului %s", OUTPUT_FILE); getch(); //Dacă fișierul poate fi deschis pentru citire, atunci trebuie închis dacă (inputFile != NULL) ( fclose(inputFile); ) exit(ERROR_OPEN_FILE); ) fscanf (inputFile, "%ud %ud", &m, &n if (m > MAX_DIMENSION) ( m = MAX_DIMENSION; ) if (n > MAX_DIMENSION) ( n = MAX_DIMENSION; ) srand(time(NULL));< 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 fie în consolă, fie copiat într-un fișier nou.

#include #include #include #define ERROR_FILE_OPEN -3 void main() ( FILE *origin = NULL; FILE *output = NULL; char nume fișier; mod int; printf("Introduceți numele fișierului: "); scanf("%1023s", nume fișier); origine = fopen (nume fișier, "r"); if (origine == NULL) ( printf("Eroare la deschiderea fișierului %s", nume fișier); getch(); exit(ERROR_FILE_OPEN); ) printf("intra în modul: "); 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(origin); exit(ERROR_FILE_OPEN); ) ) else ( output = stdout; ) while (!feof(origin)) ( fprintf (ieșire) , "%c", fgetc(origine));

3. Utilizatorul introduce date din consolă și sunt scrise într-un fișier până când tasta esc este apăsată. Vezi programul și vezi. cum se comportă dacă intri în backspace: ce este scos în fișier și ce este scos în 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(); exit(ERROR_FILE_OPEN); , stdout);

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 corect și potrivite. 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(); exit(ERROR_FILE_OPEN); ) maxn = INT_MIN; hasRead == 1) ( hasRead = fscanf(input, "%d", &num); dacă (areRead != 1) (continuare; ) dacă (num >

O altă soluție este să citim numere 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(); exit(ERROR_FILE_OPEN); ) maxn = INT_MIN; while (!feof(input)) ( fscanf(input, "%d", &num); if (num > maxn); ) ( maxn = num; ) ) printf("număr maxim = %d", maxn);

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 scoată pe cel rusesc.

Fișierul de traducere arată cam așa

soare soare
pix creion
creion cu bilă
usa usa
fereastra windows
scaun scaun
fotoliu

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

Algoritmul este următorul: citim o linie dintr-un fișier, găsim un caracter tabulator în linie, înlocuim caracterul tabulator cu un zero, copiem un cuvânt rusesc din buffer, copiem un cuvânt englezesc 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. Vom citi fișierul caracter cu caracter, numărând numărul de caractere „\n” până când vom întâlni 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 de tip 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 *filename) ( int linii = 0; int orice; //orice este de tip int deoarece EOF este de tip int! FILE *f = fopen(nume fișier, "r"); if (f == NULL ) ( return -1; ) do ( orice = fgetc(f); //printf("%c", orice);//debug if (orice == "\n") ( lines++; ) ) while(any ! = EOF); ​​​​fclose(f); 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 elevi

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

Funcția fopen() deschide un flux pentru utilizare, asociază un fișier cu acel flux și apoi returnează un pointer FILE către acel flux. Cel mai adesea fișierul este tratat ca un fișier disc. Funcția fopen() are următorul prototip:

FILE *fopen(const char *filename, const char *mode);

Unde modul indică un șir care conține modul dorit pentru deschiderea fișierului. Valorile valide pentru modul în Borland C++ sunt afișate în tabel. nume de fișier trebuie să fie un șir de caractere care furnizează un nume de fișier valid sistemului de operare și poate conține o cale.

Funcția fopen() returnează un pointer către tipul de bază FILE. Acest indicator identifică fișierul și este utilizat de majoritatea funcțiilor sistemului de fișiere. Nu ar trebui să-l schimbi niciodată singur. Funcția returnează un pointer nul dacă fișierul nu poate fi deschis.

După cum arată tabelul, fișierul poate fi deschis fie în mod text, fie în modul binar. În modul text, pe măsură ce tastați, secvența de întoarcere la cărucior și avans de linie este tradusă într-un caracter de linie nouă. La ieșire, opusul este adevărat: caracterul de linie nouă este tradus într-un retur de cărucior și un avans de linie. ÎN fișiere binare nu are loc o astfel de traducere. Când nici t, nici b nu sunt specificate în argumentul mode, atunci starea text/binară a fișierului este determinată de valoarea variabilei globale _fmode definită în Borland C++. În mod implicit, fmode este setat la O_TEXT, adică modul text este setat. Dacă setați _fmode la O_BINARY, atunci fișierele vor fi deschise în modul binar. (Aceste macrocomenzi sunt definite în fcntl.h.) Desigur, utilizarea unui t sau b explicit elimină efectele asociate cu variabila _fmode. În plus, _fmode este specific numai produselor Borland. Nu este definit în sistemul ANSI C I/O.

Dacă trebuie să deschideți un fișier numit test pentru scriere, ar trebui să scrieți:

Fp = fopen("test", "w");

Unde fp este o variabilă de tip FILE *. Cu toate acestea, este obișnuit să vedeți următoarele:

If((fp = fopen(„test”, „w”))==NULL) (
puts("Nu se poate deschide fișierul.");
ieșire(1);
}

Această metodă vă permite să detectați erori la deschiderea unui fișier, de exemplu, prezența protecției la scriere sau lipsa spațiului liber pe disc.

Dacă fopen() este folosit pentru a deschide un fișier pentru scriere, atunci orice fișier preexistent cu numele specificat va fi șters. Dacă un fișier cu numele specificat nu există, acesta va fi creat.

Dacă trebuie să adăugați informații la sfârșitul fișierului, ar trebui să utilizați modul a (adăugați). Dacă fișierul nu există, acesta va fi creat.

Deschiderea unui fișier pentru citire necesită prezența fișierului. Dacă fișierul nu există, va fi returnată o eroare. Dacă un fișier este deschis pentru operație de citire/scriere, atunci acesta nu este șters dacă există, iar dacă fișierul nu există, atunci este creat.

Tabel: Valori de mod permise

Sens

Deschide un fișier pentru citire. (Se deschide implicit ca fișier text.)

Creează un fișier în care să scrieți. (Se deschide implicit ca fișier text.)

Se atașează la un fișier. (Se deschide implicit ca fișier text.)

Deschide un fișier binar pentru citire.

Deschide un fișier binar pentru scriere.

Se atașează la un fișier binar.

Deschide un fișier pentru citire/scriere. (Se deschide implicit ca fișier text.)

Creează un fișier de citire/scriere. (Se deschide implicit ca fișier text.)

Atașează sau creează un fișier de citire/scriere. (Se deschide implicit ca fișier text.)

Deschide un fișier binar pentru citire/scriere.

Creează un fișier binar de citire/scriere.

Atașează sau creează un fișier binar de citire/scriere.

Creează un fișier text pentru scriere.

Se atașează la un fișier text.

Deschide un fișier text pentru citire.

Creează un fișier text pentru citire/scriere.

Deschide sau creează un fișier text pentru citire/scriere.