Crearea unui fișier text în c. Date introduse din fișier și ieșire în fișier

Funcția fopen() deschide un flux pentru utilizare, asociază un fișier cu fluxul dat și apoi returnează un pointer FILE către fluxul dat. De cele mai multe ori, un fișier este tratat ca un fișier de 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 de deschidere a 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 pentru sistemul de operare și poate conține o cale.

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

După cum arată tabelul, un fișier poate fi deschis fie în modul text, fie în modul binar. În modul text, când tastați, secvența de întoarcere a cărușului și de avans de linie este tradusă într-un caracter de linie nouă. La ieșire, opusul este adevărat: caracterul de nouă linie este tradus într-un retur de cărucior și un avans de linie. Nu există o astfel de traducere în fișierele binare. Când nici t, nici b nu sunt specificate în argumentul mode, 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. Setarea _fmode la O_BINARY va deschide fișierele în modul binar. (Aceste macrocomenzi sunt definite în fcntl.h.) Desigur, utilizarea unui t sau b explicit elimină efectele variabilei _fmode. În afară de asta, _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, atunci ar trebui să scrieți:

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

Unde fp este o variabilă de tip FILE *. Cu toate acestea, de obicei veți vedea 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ă, atunci 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ă fișierul este deschis pentru o operație de citire/scriere, atunci nu este șters dacă este prezent, iar dacă fișierul nu există, atunci este creat.

Tabel: Valori ale modului permis

Sens

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

Creează un fișier pentru scriere. (Se deschide ca fișier text în mod implicit.)

Se adaugă la un fișier. (Se deschide ca fișier text în mod implicit.)

Deschide un fișier binar pentru citire.

Deschide un fișier binar pentru scriere.

Se adaugă la un fișier binar.

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

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

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

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 adaugă la un fișier text.

Deschide un fișier text pentru citire.

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

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

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 structura standard de tip FILE, 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 cu fișierul.

FIȘIER *fopen(nume, tip);

nume este numele fișierului care urmează să fie deschis (inclusiv calea),
tip - un indicator 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” - fișier deschis 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ă, acesta este creat.

Valoarea returnată este un pointer către fluxul deschis. Dacă se găseș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; constanta EOF dacă a apărut o eroare.

#include
int main()

char name="my.txt";

if(fp = fopen(nume, "r")!=NULL)

// a fost posibil să deschidem fișierul?
... // acțiuni necesare asupra datelor

else printf("Nu s-a putut deschide fișierul");

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

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

fscanf(stream, „Format de intrare”, argumente);
fprintf(stream, „Format de ieșire”, argumente);

Funcțiile fgets() și fputs() sunt pentru I/O șir, sunt analoge cu funcțiile gets() și puts() pentru lucrul cu fișiere.

fgets(Pointer To String, Number Of Characters, Stream);

Caracterele sunt citite din flux până când este citit un caracter newline „\n”, care este inclus în șir, sau până la sfârșitul fluxului este EOF sau a fost citit numărul maxim de caractere. Rezultatul este plasat într-un pointer șir și terminat cu caracterul nul „\0”. Funcția returnează adresa șirului de caractere.

fputs(Pointer To String, flux);

Copiază un șir în flux din poziția curentă. Caracterul nul final nu este copiat.
Exemplu Introduceți un număr și salvați-l în fișierul s1.txt. Citiți numărul din fișierul s1.txt, măriți-l cu 3 și salvați-l în fișierul s2.txt.

Majoritatea programelor de calculator funcționează cu fișiere și, prin urmare, este nevoie de a crea, șterge, scrie, citi, deschide fișiere. Ce este un fișier? Un fișier este o colecție numită de octeți care pot fi stocați pe un dispozitiv de stocare. Ei bine, acum este clar că un fișier este o secvență de octeți care are propriul nume unic, cum ar fi un fișier .txt. Fișierele cu același nume nu pot fi în același director. Numele fișierului este înțeles nu numai ca nume, ci și ca extensie, de exemplu: fișier.txt și fișier.dat fișiere diferite, deși au același nume. Există așa ceva ca 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ă includeți un fișier antet . LA mai multe clase definite și fișiere antet incluse fisier de intrare si ieșire fișier.

File I/O este similar cu I/O standard, singura diferență este că I/O nu se face pe ecran, ci către un fișier. Dacă intrarea/ieșirea către dispozitivele standard este efectuată 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ă faceți următorii pași:

  1. creați un obiect din clasa ofstream ;
  2. asociați un obiect de clasă cu fișierul în care urmează 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, atunci va fi creat un obiect din clasa ifstream.

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

Să numim obiectul - fout , Iată ce se întâmplă:

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 urmează să fie scris șirul.

fout.open("cppstudio.txt"); // asociați obiectul cu fișierul

Prin operația punct, obținem acces la metoda clasei open(), în paranteze ale căreia indicăm numele fișierului. Fișierul specificat va fi creat în directorul curent cu programul. Dacă există un fișier cu același nume, fișierul existent va fi înlocuit cu cel nou. Deci, fișierul este deschis, rămâne să scrieți linia dorită în el. Se face astfel:

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

Folosind operația cast to stream împreună cu obiectul fout, șirul File Handling în 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

Ca 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ă într-o singură linie, creați un obiect și asociați-l cu un fișier. Se face astfel:

Ofstream fout("cppstudio.txt"); // creează un obiect din clasa ofstream și îl asociază cu 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 scriere și îl asociază cu fișierul cppstudio.txt fout<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

Rămâne să verificăm funcționarea corectă a programului și pentru aceasta deschidem fișierul cppstudio.txt și uită-te 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 urmează să fie citit;
  2. citiți fișierul;
  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 alfabetului chirilic char buff; // tampon de stocare 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 a citi 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, deoarece în fișier au rămas mai puțin de 50 de caractere, caracterele sunt citite până la ultimul, inclusiv. Rețineți că citiți a doua oară (linia 17) a continuat după primul cuvânt, și nu de la început, deoarece primul cuvânt a fost citit înlinia 14. Rezultatul programului este prezentat în Figura 1.

Lucrul cu fișierele î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 manipulat. Ca urmare, 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 simplu utilizator nu va înțelege care este problema și de ce o linie 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ă finalizăm programul cu deschiderea fișierului, în așa fel încât dacă fișierul nu este 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 caracterului chirilic buff; // tampon de stocare intermediară a textului citit din fișierul ifstream fin("cppstudio.doc"); / / ( NUME FIȘIER INSCRIS INCORECT) if (!fin.is_open()) // dacă fișierul nu este deschis cout<< "Файл не может быть открыт!\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 că fișierul nu a putut fi deschis. 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 determină modul în care sunt utilizate fișierele. Pentru a seta modul, clasa ios_base oferă constante care determină modul de deschidere a fișierului (vezi Tabelul 1).

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

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

Modurile de deschidere a fișierelor pot fi combinate folosind o operație booleană 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 din clasa ofstream , atunci când sunt asociate cu fișiere, conțin implicit moduri 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 pentru înregistrare. Obiectele clasei ifstream, atunci când sunt asociate cu un fișier, au implicit modul 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 vom folosi acest termen în viitor. Tabelul 1 nu listează toate steaguri, dar acestea ar trebui să fie suficiente pentru a începe.

Vă rugăm să 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 până la sfârșitul fișierului, iar stegulețul ate pur și simplu rearanjează steag-ul la sfârșitul fișierului. sfârșitul fișierului și nu limitează spațiul de înregistrare.

Să dezvoltăm un program care, folosind operația sizeof(), va calcula caracteristicile principalelor tipuri de date din C++ și le va scrie într-un fișier. Caracteristici:

  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 să fie în următorul format:

/* Tip de date BYTE Valoare maximă Bool = 1 255.00 Char = 1 255.00 scurt int = 2 32767.00 Nesemnat scurt Int = 2 65535.00 INT = 4 2147483647.00 UNSISGED INT = 4 4294967295.00 Long = 4 2147483647.00 UNIGNED LONG INT = 4 4294967295.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 scriere, cu trunchierea preliminară a informațiilor despre fișierul curent ( linia 14). Odată ce fișierul a fost 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 ecran, informațiile despre tipurile de date vor fi 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 la fișier, în timp ce deschideți fișierul în modul de scriere, ștergând toate datele din acesta mai întâi de flux 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 // titluri 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 în program sunt minime și totul datorită faptului că intrarea/ieșirea standard și intrarea/ieșirea fișierelor sunt folosite exact în același mod. La finalul programului,linia 45am închis în mod explicit fișierul, deși acest lucru nu este necesar, este considerat o bună practică de programare. Este de remarcat faptul că toate funcțiile și manipulatoarele utilizate pentru formatarea intrării/ieșirii standard sunt relevante și pentru intrarea/ieșirea fișierelor. Prin urmare, nu au apărut erori atunci când operatorul cout a fost înlocuit cu un obiect fout.

Înainte de aceasta, atunci când introducem și scoatem date, am lucrat cu fluxuri standard - tastatura și monitorul. Acum să ne uităm la modul în care limbajul C implementează obținerea datelor din fișiere și scrierea lor acolo. Înainte de a efectua aceste operații, fișierul trebuie deschis și accesat.

În limbajul de programare C, un pointer de fișier este de tip FILE și declarația sa arată astfel:
FIȘIER *fișierul meu;

Pe de altă parte, funcția fopen() deschide fișierul la adresa specificată ca prim argument în modul citire ("r"), scrie ("w") sau adăugare ("a") și returnează un pointer către acesta la program. Prin urmare, procesul de deschidere a unui fișier și conectare la program arată cam așa:
myfile = fopen("hello.txt", "r");

Când citiți sau scrieți date într-un fișier, acesta este accesat printr-un indicator de fișier (în acest caz, myfile).

Dacă dintr-un motiv oarecare (nu există niciun fișier la adresa specificată, accesul la acesta este interzis) funcția fopen() nu poate deschide fișierul, atunci returnează NULL. În programele reale, eroarea de deschidere a unui fișier este aproape întotdeauna gestionată în ramura if, dar vom omite acest lucru în continuare.

Declarația funcției fopen() este conținută în fișierul antet stdio.h, deci includerea acesteia este necesară. Tipul struct FILE este de asemenea declarat în stdio.h.

După terminarea lucrării cu fișierul, se obișnuiește să-l închideți pentru a elibera tamponul de date și din alte motive. Acest lucru este deosebit de important dacă programul continuă să ruleze după ce ați lucrat cu fișierul. Ruperea legăturii dintre un fișier extern și un pointer către acesta din program se face folosind funcția fclose(). Este nevoie de un indicator de fișier ca parametru:
fclose(fișierul meu);

Mai mult de un fișier poate fi deschis în program. Într-un astfel de caz, fiecare fișier trebuie să fie asociat cu propriul său indicator de fișier. Cu toate acestea, dacă programul funcționează mai întâi cu un fișier, apoi îl închide, atunci indicatorul poate fi folosit pentru a deschide un al doilea fișier.

Citirea și scrierea într-un fișier text

fscanf()

Funcția fscanf() este similară în sensul funcției scanf(), dar, spre deosebire de aceasta, preia intrare formatată dintr-un fișier, mai degrabă decât intrare standard. Funcția fscanf() preia parametri: pointer de fișier, șir de format, adrese ale zonelor de memorie pentru scrierea datelor:
fscanf(fișierul meu, „%s%d”, str, &a);

Returnează numărul de date citite cu succes sau EOF. Spațiile, caracterele newline sunt luate în considerare ca separatori de date.

Să presupunem că avem un fișier care conține următoarea descriere a obiectelor:

Mere 10 23,4 banane 5 25,0 pâine 1 10,3

#include main () ( FILE * fișier; struct food ( char name[ 20 ] ; unsigned qty; float price; ) ; struct food shop[ 10 ] ; char i= 0 ; fișier = fopen ("fscanf.txt", "r" ); în timp ce (fscanf (fișier, „%s%u%f” , magazin[ i] .nume , & (magazin[ i] .qty ) , & (magazin[ i] .preț ) ) != EOF) ( printf ("%s %u %.2f \n", magazin[ i] .nume , magazin[ i] .cantitate , magazin[ i] .preț ) ; i++; ) )

În acest caz, sunt declarate o structură și o matrice de structuri. Fiecare linie din fișier corespunde unui element al matricei; un element de matrice este o structură care conține un șir și două câmpuri numerice. Bucla citește un rând pe iterație. Când se întâlnește sfârșitul fișierului, fscanf() returnează EOF și bucla se termină.

fgets()

Funcția fgets() este similară cu funcția gets() și efectuează intrare linie cu linie dintr-un fișier. Un apel la fgets() va citi o linie. În acest caz, nu puteți citi întreaga linie, ci doar o parte din ea de la început. Opțiunile fgets() arată astfel:
fgets (array_of_characters, number_of_characters_to_read, pointer_to_file)

De exemplu:
fgets(str, 50, myfile)

Un astfel de apel de funcție va citi din fișierul asociat cu indicatorul myfile un rând de text în întregime dacă lungimea sa este mai mică de 50 de caractere, inclusiv caracterul „\n”, pe care funcția îl va stoca și în matrice. Ultimul (al 50-lea) element al matricei str va fi caracterul „\0” adăugat de fgets() . Dacă șirul este mai lung, funcția va citi 49 de caractere și va scrie „\0” la sfârșit. În acest caz, „\n” nu va fi conținut în linia de citire.

#include #define N 80 main () ( FILE * fișier; char arr[ N] ; fișier = fopen ("fscanf.txt" , "r" ) ; while (fgets (arr, N, fișier) != NULL) printf (" %s", arr); printf(" \n"); fclose(fișier); )

În acest program, spre deosebire de cel precedent, datele sunt citite linie cu linie în matricea arr. Când se citește următorul rând, cel precedent se pierde. Funcția fgets() returnează NULL dacă nu poate citi următoarea linie.

getc() sau fgetc()

Funcția getc() sau fgetc() (ambele funcționează) vă permite să obțineți următorul caracter din fișier.

în timp ce ((arr[ i] = fgetc (fișier) ) != EOF) ( dacă (arr[ i] == " \n") ( arr[i] = " \0 " ; printf("%s \n", arr) ; i = 0 ) else i++; ) arr[i] = " \0 " ; printf("%s \n", arr) ;

Codul dat ca exemplu tipărește datele dintr-un fișier pe ecran.

Scrierea într-un fișier text

La fel ca intrarea, ieșirea într-un fișier poate fi diferită.

  • Ieșire formatată. Funcția fprintf (file_pointer, format_string, variabile) .
  • Ieșire post. Funcția fputs(șir, filepointer) .
  • Ieșire simbolică. fputc() sau putc(caracter, filepointer) .

Mai jos sunt exemple de cod care folosesc trei moduri de a scoate date într-un fișier.

Scrierea pe fiecare linie a fișierului de câmp al unei structuri:

fisier = fopen("fprintf.txt" , "w" ); în timp ce (scanf ("%s%u%f", magazin[ i] .nume , & (magazin[ i] .qty ) , & (magazin[ i] .preț ) ) != EOF) ( fprintf (fișier, " %s %u %.2f \n", magazin[ i] .nume , magazin[ i] .cantitate , magazin[ i] .preț ) ; i++; )

Ieșire linie cu linie într-un fișier (fputs() , spre deosebire de puts() în sine, nu pune „\n” la sfârșitul liniei):

while (obține (arr) != NULL) ( fputs (arr, fișier) ; fputs (" \n",fişier); )

Un exemplu de ieșire caracter cu caracter:

while ((i = getchar () ) != EOF) putc (i, fisier) ;

Citirea și scrierea într-un fișier binar

Puteți lucra cu un fișier nu ca o secvență de caractere, ci ca o secvență de octeți. În principiu, este imposibil să lucrați cu fișiere non-text într-un mod diferit. Cu toate acestea, puteți citi și scrie în fișiere text în acest fel. Avantajul acestei metode de accesare a unui fișier constă în viteza de citire-scriere: un bloc semnificativ de informații poate fi citit/scris într-un singur acces.

Când deschideți un fișier pentru acces binar, al doilea argument pentru fopen() este șirul „rb” sau „wb”.

Subiectul lucrului cu fișiere binare este destul de complex, necesită o lecție separată pentru a-l studia. Doar caracteristicile funcțiilor de citire și scriere într-un fișier, care este considerat ca un flux de octeți, vor fi notate aici.

Funcțiile fread() și fwrite() iau ca parametri:

  1. adresa zonei de memorie din care sunt scrise sau citite datele,
  2. dimensiunea unuia dat de orice tip,
  3. cantitatea de date de citit de dimensiunea specificată,
  4. indicatorul de fișier.

Aceste funcții returnează numărul de date citite sau scrise cu succes. Acestea. puteți „comanda” citirea a 50 de elemente de date și obțineți doar 10. Nu va exista nicio eroare.

Un exemplu de utilizare a funcțiilor fread() și fwrite():

#include #include main () ( FIȘIER * fișier; char shelf1[ 50 ] , shelf2[ 100 ] ; int n, m; fișier = fopen ("shelf1.txt" , "rb" ) ; n= fread (shelf1, sizeof (char ) , 50 , fișier); fclose (fișier) ; fișier = fopen ("raft2.txt" , "rb" ) ; m= fread (raft2, dimensiunea (char ) , 50 , fișier) ; fclose (fișier) ; raft1[ n] = " \0 " ; raftul2[m] = " \n"; raftul2[ m+ 1 ] = " \0 " ; fisier = fopen("shop.txt" , "wb" ); fwrite (strcat (shelf2, shelf1) , sizeof (char ) , n+ m, fișier) ; fclose(fișier); )

Aici se încearcă citirea a 50 de caractere din primul fișier. n stochează numărul de caractere citite efectiv. Valoarea lui n poate fi 50 sau mai mică. Datele sunt plasate într-un șir. La fel se întâmplă și cu cel de-al doilea fișier. Apoi, prima linie este atașată la a doua, iar datele sunt aruncate în al treilea fișier.

Rezolvarea problemelor

  1. Scrieți un program care solicită utilizatorului numele (adresa) unui fișier text, apoi îl deschide și numără numărul de caractere și linii din el.
  2. Scrieți un program care scrie într-un fișier date primite dintr-un alt fișier și modificate într-un fel sau altul înainte de a fi scrise. Fiecare linie de date primită din fișier trebuie plasată într-o structură.

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

    LA 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 fel ș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 în afarăîn modul înregistrare. Un flux este utilizat pentru a lucra cu fișiere atât în ​​modul de scriere, cât și în modul de citire. fstream.

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

La 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 lecturi date dintr-un fișier text, trebuie să:

    descrie o variabilă de tip ifstream.

    deschideți un fișier 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ții î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. deschide ("fișier", mod);

Aici F este o variabilă declarată 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ă atunci când specificați numele complet al fișierului, trebuie să puneț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 citire date, acest mod este modul implicit pentru fluxurile ifstream;

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

ios::app - deschideți 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, 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. Aceasta va verifica corectitudinea operațiunii de deschidere a fișierului.

Puteți deschide un fișier (să luăm ca exemplu D:\\game\\noobs.txt) în modul de scriere folosind una dintre următoarele metode:

// primul cale

offstream F;

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

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

// pentru curgereîn afară

offstream F;

//al treilea mod combină descrierea variabilei și tipul fluxului

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

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

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

Dacă doriți să deschideți un fișier existent în modul de pre-scriere, utilizați ios::app 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, instrucțiunea de ieșire ar fi:

Pentru a imprima secvenţial variabilele b, c, d în fluxul G, instrucţiunea de ieşire devine:

G<

Fluxul este închis 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

în afară 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 numărul

cin>>a;

f<

//închiderea fluxului

f.close();

sistem(„pauză”);

returnează 0;

_______________________________________________________________

Pentru a citi informații dintr-un fișier text, este necesar să declarați o variabilă de tip ifstream. După aceea, trebuie să deschideți fișierul pentru citire folosind operatorul deschis. Dacă variabila se numește F, atunci primele două afirmații vor fi după cum urmează:

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 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, tabulator, caracter de final de linie. Este bine dacă programatorul știe dinainte câte și ce valori să stocheze într-un fișier text. Cu toate acestea, adesea tipul de valori stocate în fișier este pur și simplu cunoscut, iar 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 fluxului, 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 î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:\\game\\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");

intn=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 buclei va fi întreruptă,

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

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

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

F>>a;

//se scoate pe ecran valoarea variabilei a

cout<

//crește numărul de numere citite

//închiderea fluxului

f.close();

//introducerea numărului de numere citite pe ecran

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++. 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.

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

    declara o variabilă de fișier de tip FAIL * folosind instrucțiunea 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

La gândi z 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 cu funcția fclose

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

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

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 definește 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 scriere; dacă există, conținutul său este șters;

"ab" - creați sau deschideți un fișier binar pentru a fi adăugat la sfârșitul fișierului;

"rb+" - deschideți un fișier binar existent în modul citire-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ă valoarea NULL în variabila fișier f dacă fișierul nu a fost deschis cu succes. După deschiderea fișierului, al 0-lea octet al acestuia este disponibil, indicatorul fișierului este 0, a cărui valoare este deplasată de 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 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 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 elimină un fișier numit fileema de pe disc. 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 la finalizarea cu succes a programului.

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 de dimensiune din numele fișierului în matricea ptr. Funcția returnează numărul de elemente citite. După citirea dintr-un fișier, indicatorul acestuia este deplasat cu n*size octeți.

Î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ă ce informațiile sunt scrise în fișier, indicatorul este deplasat cu n*size octeți.

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

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 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:\\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;

// scrieți numărul real în fișierul 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șierului

//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="<

//aloca memorie 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;

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ă trebuie să numărați al cincisprezecelea număr și apoi primul. Cu acces serial, 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 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 conformitate cu valoarea originii și offset-ul. 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 pentru 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ă zero dacă operația are succes, diferit de zero dacă offset-ul eșuează.

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. Luați în considerare utilizarea accesului direct în fișierele binare folosind exemplul de rezolvare a următoarei probleme.

EXEMPLU

În fișierul binar D:\\game\\noobs.dat creat mai devreme, schimbați cel mai mare și cel mai mic dintre numerele reale.

Algoritmul de rezolvare a problemei constă din următorii pași:

    citirea reale dintr-un fișier într-o 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ți fișierul în modul citire/scriere

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

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

//numerele reale din fișier

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

cout<<"n="<

//aloca memorie pentru a stoca numere reale,

//care va fi stocat în tabloul a

a=dublu nou[n];

//citește din fișier într-o matrice și numere reale

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

//căutaț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);

//înregistrarea minului în loc de elementul maxim al fișierului

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

// in miscare indicator la minim element

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

//Înregistrează maxim î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ă”);

  • Serghei Savenkov

    un fel de recenzie „rare”... parcă s-ar grăbi undeva