Este posibil să scrieți informații dincolo de sfârșitul fișierului? Lucrul cu fișiere text

Fișiere text

Să luăm în considerare lucrul cu fisier textîn C cu un exemplu. Creați un fișier text pe unitatea C denumit 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 un program 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, iar al treilea este fișierul nostru.

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

fclose(pTextFile);

Primim:

În rânduri apar și litere rusești.

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 vom învăța cum să creăm 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);

Creați un fișier text în care să scrieți date:

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

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

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

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.

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ă se blocheze în memorie, eventual chiar și după ce programul este închis (de exemplu, nu va fi posibilă ștergerea deschide fișierul sau efectuaț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 în el Salut Lume

#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. Creată fișier nou. Dacă un fișier cu același nume există deja, conținutul acestuia se va pierde. Poț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ă ne completăm program vechi: Să redeschidem fișierul și să 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ăugăm imediat aici că funcții printf iar scanf poate fi înlocuit 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: fluxul de ieșire standard stdout, fluxul de intrare standard stdin și fluxul de ieșire standard de eroare 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, fclose(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 actualul stație de lucru 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 mod 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 linie nouă. 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 corect și potrivite.

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

Exemple

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

#include #include #include #include //Numele și permisiunile fișierelor #define INPUT_FILE "D:/c/input.txt" #define OUTPUT_FILE "D:/c/output.txt" #define READ_ONLY "r" #define WRITE_ONLY "w" //Valoarea maximă pentru matrice dimensiune #define MAX_DIMENSION 100 //Eroare la deschiderea fișierului #define ERROR_OPEN_FILE -3 void main() ( FILE *inputFile, *outputFile; unsigned m, n; unsigned i, j; inputFile = fopen(INPUT_FILE, READ_ONLY); 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 acestea sunt scrise într-un fișier până când se apasă butonul. tasta esc. 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 următoarele 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 nu a fost găsit"); ) 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 are 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ă

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 informatie necesara despre dosar.

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),
tip - 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” - deschis dosar gol pentru înregistrare; 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ă este detectată 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.

#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("Deschiderea fișierului a eșuat");

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 către fișier ca prim argument.

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

Funcțiile fgets() și fputs() sunt concepute pentru intrarea/ieșirea șirurilor de caractere sunt analoge cu funcțiile gets() și puts() pentru lucrul cu fișiere.

fgets(Pointer To Line, Numar de caractere, flux);

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ă când fluxul se termină EOF sau a fost citit numărul maxim de caractere. Rezultatul este plasat într-un indicator și se termină 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 numărul și salvați-l în fișierul s1.txt. Citiți numărul din fișierul s1.txt, creșteți-l cu 3 și salvați-l în fișierul s2.txt.

Funcția fopen() deschide un flux pentru utilizare, asociază un fișier cu acel flux și apoi returnează un pointer FILE la acest curent. Cel mai adesea fișierul este vizualizat ca 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. numele fișierului trebuie să fie un șir de caractere care furnizează nume corect fişier sistem de operare, și poate conține o indicație de cale.

Funcția fopen() returnează un pointer tip de bază FIŞIER. Acest indicator identifică fișierul și este utilizat de majoritatea funcțiilor. Sistemul 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 modul 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 nouă linie 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ă este setat modul text. 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);
}

Aceasta metoda 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.

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 să lucrați cu un fișier text, trebuie să definiți o variabilă de tip de flux. 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ț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, altfel 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 înainte, 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ă: true sau false, în funcție de atingerea sfârșitului 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ă valoarea NULL în variabila fișier f dacă deschiderea fișierului eșuează. 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ă a avut loc un eșec în timpul execuției offsetului

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

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