Cum se configurează smartphone-uri și PC-uri. Portal informativ
  • Acasă
  • Windows 7, XP
  • Deschiderea unui fișier. Date introduse din fișier și ieșire în fișier

Deschiderea unui fișier. Date introduse din fișier și ieșire în fișier

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

    Î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 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 folosit 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.

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

    descrie o variabilă de tip de flux.

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

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

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

    inchide fisierul.

Î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 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ă acesta 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 ș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, tabulație, 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.

Pentru a 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

Pentru a 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 vechiul nume al fișierului, 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 î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 numerelen

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

//iesire 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ă în 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 variabila n număr

//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ă”);

Fișiere text

Să luăm în considerare lucrul cu un fișier text în C folosind un exemplu. Creați un fișier text pe unitatea C numit TextFile.txt. Introduceți următoarele rânduri în acest fișier:

String_1 123 String_11, 456
String_2
String_3

Salvați fișierul.

Și acesta este codul pentru programul C care deschide fișierul nostru și citește linii din el:

/* *Autor: @author Subbotin B.P..h> #include #define LEN 50 int main(void) (puts("Operațiuni cu fișierul text"); char cArray; FILE *pTextFile = fopen("C:\\TextFile.txt", "r"); if(pTextFile == NULL) (puts("Probleme"); return EXIT_FAILURE; ) while(fgets(cArray, LEN, pTextFile) != NULL) ( printf("%s", cArray); ) fclose(pTextFile); return EXIT_SUCCESS; )

Pentru a deschide un fișier text în C, utilizați funcția fopen:

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

Primul argument al funcției fopen indică un fișier, iar al doilea spune că fișierul este deschis pentru citire din el.

Citim liniile folosind funcția fgets:

fgets(cArray, LEN, pTextFile);

Primul argument al funcției fgets indică o matrice de caractere în care vor fi stocate șirurile primite, al doilea argument este numărul maxim de caractere de citit, al treilea este fișierul nostru.

După ce ați terminat de lucrat cu fișierul, trebuie să îl închideți:

fclose(pTextFile);

Primim:

Trec și litere rusești din rânduri.

Apropo, am făcut acest program în Eclipse. Puteți vedea cum să lucrați cu C/C++ în Eclipse.

Deci, am deschis și am citit datele dintr-un fișier text.

Acum să învățăm cum să creăm în mod programatic un fișier text și să scriem date în el.

/* Autor: @author Subbotin B.P..h> #include int main(void) ( FILE *pTextFile = fopen("C:\\TextFileW.txt", "w"); char *cString = "Acesta este un șir"; char cNewLine = "\n"; int nVal = 123 ; if(pTextFile == NULL) (puts(„Probleme”); return EXIT_FAILURE; ) fprintf(pTextFile, „%s%c”, cString, cNewLine); fprintf(pTextFile, „%d”, nVal); return EXIT_SUCCESS ;)

Creați un fișier text pentru a scrie date în el:

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

dacă fișierul există deja, acesta va fi deschis și toate datele vor fi șterse din el.

C-string cString și numărul nVal sunt scrise de program într-un fișier text. cNewLine este doar o întrerupere de linie.

Scriem date într-un fișier text folosind funcția fprintf:

fprintf(pTextFile, „%s%c”, cString, cNewLine);

primul argument aici este fișierul nostru, al doilea este șirul de format, al treilea sau mai multe este numărul de argumente necesare pentru acest format.

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

Fișierul este o zonă denumită a memoriei externe alocată pentru stocarea unei matrice de date. Datele conținute în fișiere sunt de cea mai diversă natură: programe în limbaj algoritmic sau mașină; date inițiale pentru funcționarea programelor sau rezultatele execuției programului; texte arbitrare; grafica, 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 este o parte funcțională a sistemului de operare care oferă operațiuni asupra fișierelor. Exemple de sisteme de fișiere sunt FAT (FAT - File Allocation Table, file allocation table), NTFS, UDF (utilizat pe CD-uri).

Există trei versiuni majore de FAT: FAT12, FAT16 și FAT32. Ele diferă prin bitness al înregistrărilor în 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 mici, FAT32 pentru unități FLASH de mare capacitate (până la 32 GB).

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

Structura fișierului FAT32

Dispozitivele de memorie externă din sistemul FAT32 nu sunt octeți, ci adrese de bloc. Informațiile sunt scrise pe un dispozitiv de memorie extern în blocuri sau sectoare.

Sector - 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 asociere 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 #2 este folosit de directorul rădăcină, iar pornind de la clusterul #3, matricea de date este stocată. Sectoarele utilizate pentru stocarea informațiilor deasupra directorului rădăcină nu sunt grupate.
Dimensiunea minimă a fișierului de pe disc este 1 cluster.

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

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

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

  • 0x10 (1 octet) – numărul de tabele FAT (de obicei 2);
  • 0x20 (4 octeți) - numărul de sectoare de pe disc;
  • 0x2C (4 octeți) – numărul 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ă nu este cunoscut;
  • 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 (corespunzător stării clusterelor 0 și 1, absent fizic). În plus, starea fiecărui cluster conține numărul clusterului în care fișierul curent continuă sau următoarele informații:

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

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

Când lucrați cu nume lungi de fișiere (inclusiv nume rusești), numele fișierului este codificat în 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 sub forma următoarei structuri:

  • secvență de 1 octet;
  • 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șierele în 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 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 asupra fișierului.

FIȘIER *fopen(nume, tip);


nume este numele fișierului care trebuie deschis (inclusiv calea),
tipul este 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" - deschideți fișierul pentru scriere până la sfârșit (pentru anexare); fisierul este creat daca nu exista;
  • „r+” - fișier deschis 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.

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( "Fișierul nu poate fi deschis");
getchar();
returnează 0;
}
// Deschiderea fișierului a reușit
... // 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 caracter într-un fișier:

fputc(personaj, flux);

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

Funcțiile fscanf() și fprintf() sunt similare 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, "InputFormat" , args);

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 trebuie 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 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(personaj, flux);

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

Funcțiile fscanf() și fprintf() sunt similare 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 de nouă linie „\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.

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.

Mecanismul I/O dezvoltat de , nu corespunde stilului de programare orientat pe obiecte general acceptat astăzi, în plus, utilizează activ operațiuni cu pointer, care sunt considerate potențial nesigure în mediile moderne de execuție a codului securizat. O alternativă pentru dezvoltarea aplicațiilor este mecanismul standard al clasei I/O oferit de standardul limbajului C++.

Deschiderea fișierelor

Cele mai frecvent utilizate clase sunt ifstream pentru citire, ofstream pentru scriere și fstream pentru modificarea fișierelor.

Toate clasele I/O threaded sunt derivate indirect din strămoșul comun ios , moștenind pe deplin funcționalitatea acestuia. De exemplu, membrul de date enumerat open_mode specifică modul de deschidere a fișierului, care este definit după cum urmează:

Enum open_mode (aplicație, binar, in, out, trunc, ate);

Mai jos sunt posibilele valori ale steagurilor și scopul lor.

De exemplu, pentru a deschide un fișier numit test.txt pentru a citi date binare, ați scrie:

fișier ifstream; fișier.open(„test.txt”, ios::in | ios::binar);

Operatorul logic SAU (|) vă permite să compuneți un mod cu orice combinație de steaguri. Pentru ca atunci când deschideți un fișier prin scriere, să nu suprascrieți accidental un fișier existent cu același nume, trebuie să utilizați următorul formular:

fișier offstream; fișier.open(„test.txt”, ios::out | ios::app);

Se presupune că fișierul antet corespunzător este conectat la proiect:

#include

Pentru a verifica dacă fișierul a fost deschis cu succes, puteți folosi construcția

Dacă (!fișier) ( // Gestionarea unei erori de deschidere a fișierului )

Operatori de incluziune și extracție

Suprascris în clasele de gestionare a fișierelor include operator (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

Fişier<< "Это строка текста";

De asemenea, puteți scrie un șir de text în părți:

Fişier<< "Это " << "строка " << "текста";

Instrucțiunea endl încheie intrarea de linie cu un return car:

Fişier<< "Это строка текста" << endl;

Folosind operatorul include, este ușor să scrieți valorile variabilelor sau elementelor matricei într-un fișier:

Fișier ofstream ("Temp.txt"); char buff = "Matricea de text conține variabile"; int vx = 100; float pi = 3,14159; fişier<< buff << endl << vx << endl << pi << endl;

Ca rezultat al execuției codului, sunt generate trei rânduri ale fișierului text Temp.txt:

Matricea text conține variabile 100 3.14159

Rețineți că valorile numerice sunt scrise în fișier ca șiruri de text, nu valori binare.

operator de extragere(>>) face invers. S-ar părea că pentru a extrage caracterele din fișierul Temp.txt scris mai devreme, trebuie să scrieți cod ca următorul:

fișier ifstream ("Temp.txt"); char buff; intvx; floatpi; fisier >> buff >> vx >> pi;

Cu toate acestea, operatorul de extracție se va opri la primul delimitator (spațiu, tabulator sau linie nouă) pe care îl întâlnește. Astfel, la analizarea propoziției „Text array contains variables”, doar cuvântul „Text” va fi scris în matricea bufantă, spațiul este ignorat, iar cuvântul „array” va deveni valoarea variabilei întregi vx și codul. execuția se va „încălca” cu o încălcare inevitabilă a structurii datelor. În continuare, când discutăm despre clasa ifstream, vom arăta cum să organizăm corect citirea fișierului din exemplul anterior.

clasa ifstream: citirea fișierelor

După cum sugerează și numele, clasa ifstream este concepută pentru a introduce un flux de fișiere. Principalele metode ale clasei sunt enumerate mai jos. Cele mai multe dintre ele sunt moștenite din clasa istream și supraîncărcate cu funcționalitatea părinte. De exemplu, funcția get, în funcție de parametrul de apel, este capabilă să citească nu numai un singur caracter, ci și un bloc de caractere.

Acum este clar cum trebuie să modificați exemplul anterior, astfel încât utilizarea operatorului de extracție a datelor să dea rezultatul așteptat:

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

Metoda getline va citi prima linie a fișierului până la sfârșit, iar operatorul >> va atribui valori variabilelor.

Următorul exemplu arată adăugarea de date la un fișier text și apoi citirea întregului fișier. Bucla while (1) este folosită în loc de while(!file2.eof()) din motive discutate în .

#include #include folosind namespace std; int main() (fișier ofstream; fișier.open("test.txt",ios::out|ios::app); if (!fișier) (cout<< "File error - can"t open to write data!"; cin.sync(); cin.get(); return 1; } for (int i=0; i<10; i++) file << i << endl; file.close(); ifstream file2; file2.open("test.txt", ios::in); if (!file2) { cout << "File error - can"t open to read data!"; cin.sync(); cin.get(); return 2; } int a,k=0; while (1) { file2 >>a; if (file2.eof()) break; cout<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

Următorul exemplu trece prin citirea liniilor din fișierul test.txt și afișarea lor pe consolă.

#include #include folosind namespace std; int main() (fișier ifstream; // creează un fișier obiect flux file.open("test.txt"); // deschide fișierul pentru citire dacă (!fișier) returnează 1; // returnează la eroare deschiderea caracterului str; / / static line buffer // Citiți și afișați liniile într-o buclă până la eof while (!file.getline(str, sizeof(str)).eof()) cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

Acest cod sub sistemul de operare Windows depinde și de prezența unui caracter de linie nouă în ultima linie a fișierului, ar fi mai fiabil să faceți acest lucru:

În timp ce (1) ( dacă (file.eof()) break; file.getline(str, sizeof(str)); cout<< str << endl; }

Apelurile explicite la metodele de deschidere și închidere sunt opționale. Într-adevăr, apelarea constructorului cu un argument vă permite să deschideți fișierul imediat, în momentul în care obiectul flux de fișiere este creat:

fișier ifstream ("test.txt");

În loc de metoda de închidere, puteți utiliza operatorul de ștergere, care va apela automat destructorul obiectului fișierului și va închide fișierul. Codul în buclă while oferă verificarea corespunzătoare a sfârșitului fișierului.

ofstream class: scrierea fișierelor

Clasa ofstream este concepută pentru a scoate date dintr-un flux de fișiere. Principalele metode ale acestei clase sunt enumerate mai jos.

Operatorul include descris mai devreme este convenabil pentru organizarea scrierii într-un fișier text:

Fișier ofstream ("temp.txt"); if (!file) return; pentru (int i=1; i<=3; i++) file << "Строка " << i << endl; file.close();

Binare

În principiu, datele binare sunt servite ca și date text. Diferența este că, dacă datele binare sunt scrise într-o anumită structură logică, atunci acestea trebuie citite din fișier într-o variabilă de același tip de structură.

Primul parametru al metodelor de scriere și citire (adresa blocului de scriere/citire) trebuie să fie de tipul unui pointer caracter char * , deci este necesar să se convertească în mod explicit tipul adresei structurii void *. Al doilea parametru specifică faptul că blocurile binare ale fișierului au o dimensiune constantă de octeți, indiferent de lungimea reală a înregistrării. Următorul apendice oferă un exemplu despre cum să creați și să afișați date într-un blocnotes simplu. Înregistrările fișierului sunt apoi citite secvențial și afișate pe consolă.

#include #include #include folosind namespace std; struct Note ( // structura de date a notebook-ului char Nume; // nume complet char Telefon; // telefon int Vârstă; // vârstă ); int main() ( setlocale(LC_ALL, „rusă”); Note1= („Grozny Ioann Vasilyevich”, „neinstalat”, 60); Note2= („Godunov Boris Fedorovich”, „095-111-2233”, 30 ); Note Note3= ( „Peter Romanov „, „812-333-2211 „, 20 ); ofstream ofile(„Notebook.dat”, ios::binary); ofile.write((char*)&Note1, sizeof ( Note)); // primul bloc ofile.write((char*)&Note2, sizeof(Notes)); // al 2-lea bloc ofile.write((char*)&Note3, sizeof(Notes)); // al 3-lea bloc ofile. close(); // închide fișierul scris ifstream ifile("Notebook.dat", ios::binary); Note Note; // variabilă structurată char str; // buffer șir static // Citește și afișează linii într-o buclă până când eof while (!ifile.read((char*)&Notă, sizeof(Notes)).eof()) ( sprintf(str, „%s\tBody: %s\tAge: %d" , Notă.Nume, Notă. Telefon, Notă.Vârsta); cout<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

Ca urmare a executării acestui cod, un fișier binar Notebook.dat este format din trei blocuri de 80 de octeți fiecare (presupunând că caracterele sunt de un singur octet). Desigur, puteți utiliza alte metode de streaming și puteți efectua orice operație pe câmpurile unei anumite structuri de date.

fstream class: acces aleatoriu la fișiere

Să presupunem că caietul nostru a acumulat 100 de intrări și vrem să numărăm al 50-lea. Desigur, puteți organiza o buclă și puteți citi toate înregistrările de la prima până la cea dată. Evident, o soluție mai orientată este să setați indicatorul de poziție a fișierului pos direct la intrarea 50 și să o citiți:

ifstream ifile("Notebook.dat", ios::binary); int pos = 49 * sizeof(Note); ifile seek(pos); // caută intrarea a 50-a Note Note; //Note - structura „înregistrare” descrisă mai sus ifile.read((char*)&Note, sizeof(Notes));

Astfel de operațiuni de căutare sunt eficiente dacă fișierul constă din înregistrări de dimensiune cunoscută și constantă. Pentru a înlocui conținutul unei intrări arbitrare, trebuie să deschideți fluxul de ieșire în modul de modificare:

Ofstream ofile("Notebook.dat", ios::binary | ios::ate); int pos = 49 * sizeof(Note); ofile seekp(pos); // caută nota a 50-a Note Note50 = („Elțin Boris Nikolaevici”, „095-222-3322”, 64); ofile.write((char*)&Notă, sizeof(Note)); // înlocuire

Dacă nu specificați indicatorul ios::ate (sau ios::app), atunci când deschideți fișierul binar Notebook.dat, conținutul său anterior va fi șters!

În cele din urmă, este posibil să deschideți un fișier concomitent pentru citire/scriere, folosind metode moștenite de clasa de streaming fstream de la predecesorii săi. Deoarece clasa fstream este derivată din istream și ostream (părinții ifstream și, respectiv, ofstream), toate metodele menționate anterior devin disponibile pentru aplicație.

Următorul exemplu schimbă prima și a treia intrare din fișierul Notebook.dat.

#include #include #include folosind namespace std; struct Note ( char Nume; char Telefon; int Vârstă; ); int main() ( setlocale(LC_ALL, „rusă”); Note1, Note3; // Deschide fișierul pentru citirea/scrierea simultană a fișierului fstream(„Notebook.dat”, ios::binary | ios::in | ios:: out); file.seekg(2 * sizeof(Note)); // găsiți și citiți Note3 file.read((char*)&Note3, sizeof(Notes)); file.seekg(0); // găsiți și citiți Nota1 file.read((car*)&Notă1, dimensiunea(Note)); file.seekg(0); //Notă1<== Note3 file.write((char*)&Note3, sizeof(Notes)); file.seekg(2 * sizeof(Notes)); // Note3 <== Note1 file.write((char*)&Note1, sizeof(Notes)); char str; // Считывать и отображать записи в цикле, пока не eof file.seekg(0); // вернуться к началу файла while (!file.read((char*)&Note1, sizeof(Notes)).eof()) { sprintf(str, "%s\tТел: %s\tВозраст: %d", Note1.Name, Note1.Phone, Note1.Age); cout << str << endl; } file.close(); cin.sync(); cin.get(); return 0; }

Indicatoarele ios::in și ios::out trebuie specificate în constructorul obiectului fișier pentru a permite operațiuni de citire și scriere simultane. Ca urmare a executării acestui cod, prima și a treia înregistrări ale fișierului binar Notebook.dat vor fi schimbate.

Există exemple suplimentare pe această temă.

Top articole similare