4.1. operatii de intrare / iesire la nivel de caracter Scrierea unui caracter într-un fisier se face folosind functia: int fputc(int c, FILE *pf); Functia întoarce primul parametru sau EOF, în caz de eroare. Citirea unui caracter dintr-un fisier se face cu functia: int fgetc(FILE *pf); Functia întoarce ca rezultat urmatorul caracter citit din fisier, convertit în întreg fara semn sau EOF daca s-a citit sfârsit de fisier sau s-a produs o eroare la citire. Scrieti un program care realizeaza copierea unui fisier. Numele celor doua fisiere (sursa si destinatie) sunt citite de la terminal. #include <stdio.h> /* copierea unui fisier */ void copiere1(FILE *, FILE *); void main(void) void copiere1(FILE *d, FILE *s) 4.2. operatii de intrare / iesire pentru siruri de caractere char *fgets(char *s, int n, FILE *pf); - citeste caractere din fisierul cu pointerul pf, pâna la întâlnirea primului caracter '\n' (cel mult n-1 caractere) în tabloul s; pune la sfârsit '\n' si '\0' - întoarce s sau NULL la întâlnire sfârsit de fisier sau la eroare Scrieti o functie care simuleaza functia fgets(). char *fgets(char *s, int n, FILE *pf)
int fputs(char *s, FILE *pf); - copiaza sirul în fisierul de iesire - nu copiaza terminatorul de sir '\0' - întoarce un rezultat nenegativ (numarul de caractere scrise în fisier), sau EOF la producerea unei erori
Scrieti o functie care simuleaza functia fputs(). int fputs(char *s, FILE *pf)
return (ferror(pf)) ? EOF: n; } Copierea unui fisier folosind functii orientate pe siruri de caractere are forma: #define MAX 100 void copiere2(FILE *d, FILE *s) Revenim acum asupra modurilor de acces la disc. Sunt posibile urmatoarele situatii: 1. fisierul nu exista; dorim sa-l creem si sa punem informatii în el - "w" - deschidere pentru scriere, noile scrieri se fac peste cele vechi 2. fisierul exista deja; dorim sa extragem informatii din el - "r" - deschidere pentru citire, fisierul trebuie sa existe deja - "r+" - citire si scriere ; fisierul trebuie sa existe 3. fisierul exista deja; dorim sa adaugam informatii la el, pastrând informatiile deja existente - "a" - deschidere pentru adaugare, toate scrierile se adauga la sfârsitul fisierului existent sau nou creat - "a+" - citire si adaugare; daca fisierul nu exista, el va fi creat 4. fisierul exista deja; dorim sa punem alte informatii în el stergând pe cele existente - "w+" - citire si scriere; daca fisierul exista deja el este sters Modul de acces binar se specifica cu sufixul "b". Astfel avem: "rb", "w+b" Modul text este considerat implicit, dar poate fi specificat explicit prin "t". 4.3. operatii de intrare / iesire cu format - scrierea cu format int fprintf(FILE *pf, char *format, lista_expresii); - transfera în fisierul specificat, valorile expresiilor, convertite, potrivit formatului în caractere - întoarce numarul de caractere scrise, sau o valoare negativa, daca s-a produs o eroare. Un descriptor de conversie din format începe prin % si poate avea un mai multi specificatori optionali, care preced descriptorul: %[indicator][latime][.precizie][spec_lung]descriptor; Indicatorul poate avea una din valorile: - aliniere stânga + afisare numere cu semn 0 completare stânga cu zerouri adaugare spatiu înaintea primei cifre, daca numarul este pozitiv # %#o - scrie 0 initial %#x - scrie 0x %#e,f,g,E,G - scrie punctul zecimal si nu elimina zerourile la sfârsit Latimea - numar ce indica latimea minima a câmpului în care se face scrierea. * latimea este data de argumentul urmator Precizia este un numar interpretat diferit în functie de descriptorul folosit.Astfel: %e, %E, %f - numarul de cifre dupa punctul zecimal %s -numarul maxim de caractere afisate %g, %G - numarul de cifre semnificative %d, %i - numarul minim de cifre (cu zerouri în fata) Specificarea lungimii se face prin: H - short l - long L - long double
- citirea cu format int fscanf(FILE *pf, char *format, lista_adrese_variabile); - se citesc date din fisierul pf, sub controlul formatului, initializându-se variabilele din lista - functia întoarce numarul de câmpuri citite sau EOF în caz de producere a unui incident la citire sau întâlnire a marcajului de sfârsit de fisier.
4.4. intrari / iesiri în modul de acces binar - sunt operatii de transfer (citiri / scrieri) fara conversii - se fac la nivel de articol - pozitia în fisier este actualizata dupa fiecare citire / scriere unsigned fread(void *zona, unsigned la, unsigned na, FILE *pf); - citeste cel mult na articole, de lungime la fiecare, din fisierul pf în zona - întoarce numarul de înregistrari citite sau 0 în caz de eroare sau sfârsit de fisier unsigned fwrite(void *zona, unsigned la, unsigned na, FILE *pf); - scrie na articole de lungime la, din zona în fisierul pf - întoarce numarul de articole scrise. Pentru a copia un fisier binar (sau text) folosind functiile fread() si fwrite() vom considera lungimea articolului 1 octet. void copiere3(FILE * d, FILE * s) 5. Operatii pentru fisiere cu acces direct. 5.1. Pozitionarea în fisier int fseek(FILE *pf, long depl, int orig); - modifica pozitia curenta în fisierul cu pointerul pf cu depl octeti relativ la cel de-al treilea parametru orig, dupa cum urmeaza: · fata de începutul fisierului, daca orig=0 (sau SEEK_SET) · fata de pozitia curenta, daca orig=1 (sau SEEK_CUR) · fata de sfârsitul fisierului, daca orig=2 (sau SEEK_END) - întoarce rezultatul 0 pentru o pozitionare corecta, si diferit de 0 în caz de eroare. void rewind(FILE *pf); realizeaza o pozitionare la începutul fisierului, fiind echivalent cu: fseek(pf, 0L, SEEK_SET);
long ftell(FILE *pf); - întoarce pozitia curenta în fisier, exprimata prin numarul de octeti fata de începutul fisierului Scrieti o functie care determina numarul de octeti ai unui fisier. #include <stdio.h> long FileSize(FILE *pf)
tratarea erorilor int feof(FILE *pf); - întoarce o valoare diferita de 0, daca s-a detectat marcajul de sfârsit de fisier int ferror(FILE *pf); - întoarce o valoare diferita de 0, daca s-a detectat o eroare în cursul operatiei de intrare / iesire
Fisierul "comenzi.dat" contine articole structuri cu câmpurile: -denumire produs- un sir de 20 de caractere -cantitate comandata - o valoare reala. Fisierul "depozit.dat" este format din articole având câmpurile: - denumire produs - un sir de 20 de caractere - stoc si stoc_minim- valori reale - pret unitar - valoare reala Sa se actualizeze fisierul de stocuri, prin onorarea comenzilor. O comanda este onorata, daca prin satisfacerea ei, stocul ramas în magazie nu scade sub stocul minim. Se va creea un fisier "facturi.dat", continând pentru fiecare comanda onorata, denumirea produsului comandat si valoarea comenzii. Se vor crea de asemeni doua fisiere, unul cu comenzi care nu au fost satisfacute, deoarece produsele erau în cantitati insuficiente, celalalt cu comenzi de produse care nu exista în depozit.
#include <stdio.h> #include <stdlib.h> typedef struct comanda; typedef struct depozit; typedef struct factura; void main(void) ; if((fd=fopen("depozit.dat","r+b"))==NULL); ff=fopen("facturi.dat","wb"); fc1=fopen("com1.dat","wb"); fc2=fopen("com2.dat","wb"); while(1) else fwrite(&com, sizeof(com), 1, fc1); break; } } } while(!gasit && !eof); if(!gasit) fwrite(&com, sizeof(com), 1, fc2); } fclose(fc); fclose(fd); fclose(ff); fclose(fc1); fclose(fc2); }
Fisiere în C++. Realizarea functiilor de intrare/iesire în C++ se realizeaza prin intermediul fluxurilor (streamuri). Un flux este o clasa. Fluxurile pot fi clasificate în: - fluxuri de intrare/iesire standard - fluxuri de intrare/iesire folosind fisiere - fluxuri de intrare/iesire în memorie În instructiunea cout << x; cout este un obiect de tip flux de iesire standard. Transferul informatiei în fisier se realizeaza prin intermediul operatorului << supraîncarcat. cin este obiectul flux de intrare standard; transferul informatiei se face prin operatorul supraîncarcat >>. Obiectele cin si cout sunt declarate în iostream.h. Utilizatorul îsi defineste propriile fluxuri, declarându-le ca obiecte în clasele: ofstream., pentru operatii de scriere ifstream, pentru operatii de citire fstream, pentru operatii atât de citire, cît si de scriere Pentru a folosi aceste clase trebuie inclus fisierul antet fstream.h . Deschiderea unui fisier (asocierea fisier - stream) se face cu functia membru open(), avînd semnatura: void open(char* numefisier, int mod, int acces); Modul în care poate fi deschis un fisier este precizat în clasa ios prin enumeratorii: in - fisierul se deschide pentru citire; fisierul trebuie sa existe out - fisierul se deschide pentru scriere; daca exista - se sterge si se creaza un nou fisier ate - fisierul se deschide pentru adaugare la sfârsit, daca nu exista - se creaza app - fisierul se deschide pentru adaugare la sfârsit; fisierul trebuie sa existe trunc - daca fisierul exista, va fi sters si se va crea un fisier nou pentru scriere nocreate - fisierul deschis trebuie sa existe (el nu poate fi creat) noreplace - fisierul este deschis, iar continutul lui nu poate fi înlocuit binary - fiserul deschis va fi prelucrat ca un fisier binar ifstream f; Modul de acces poate specifica una din valorile: 0 - fisier fara restrictii de acces 1 - fisier protejat la scriere 2 - fisier ascuns 4 - fisier sistem 8 - fisier arhiva Desfacerea legaturii fisier - stream se face folosind functia close(). Operatorii de insertie (<<) si extractie (>>) sunt supraîncarcati, putând fi folositi pentru a scrie, respectiv citi din fisier.
Exemplu: #include <fstream.h> 5. Probleme propuse. 1. Sa se scrie un program pentru creerea unui fisier binar, având articole structuri cu urmatoarele câmpuri: · Nume depunator - sir de maxim 30 de caractere · Data depunerii - o structura având câmpurile întregi: zi, luna, an. · Suma depusa - o valoare reala. Articolele sunt grupate pe zile în ordine cronologica. Datele se introduc de la consola, fiecare pe trei linii.
2. Sa se scrie un program care folosind fisierul creat în problema 1 calculeaza si afiseaza: · Suma maxima depusa, împreuna cu data si numele depunatorului. · Numarul depunerilor din fiecare zi, si suma totala depusa în fiecare zi, tinând cont ca tranzactiile dintr-o zi sunt contigue în fisier.
3. Sa se scrie un program pentru actualizarea fisierului creat în problema 1, pe baza unor foi de restituire, introduse de la tastatura, continând numele si suma solicitata. Programul semnaleaza la consola urmatoarele situatii: · Solicitant inexistent · Suma solicitata depaseste soldul. Fisierul actualizat este listat la consola.
4. Sa se scrie un program, care folosind fisierul creat în problema 1 actualizeaza acest fisier prin adaugarea dobânzii la data curenta. Se precizeaza urmatoarele date: · Data curenta la care se calculeaza dobânda (an, luna, zi) · Dobânda anuala Se va folosi o functie care determina numarul de zile între data depunerii si data curent, pentru a calcula dobânda cuvenita.
1. Pentru a sorta elementele unui tablou T, fara a le deplasa, se creeaza un nou tablou P, în care un element PI reprezinta pozitia pe ar ar avea-o elementul corespunzator din T în tabloul sortat, adica numarul de elemente care ar trebui sa se gaseasca înaintea fiecarui element din tabloul sortat.:
Pe baza tabloului P se obtine relativ simplu pozitia (indexul) elementelor sortate din tabloul T. Cel mai mic element se afla în T în pozitia k, astfel încât Pk=0, urmatorul - în pozitia corespunzatoare lui Pk=1, ultimul element corespunde pozitiei k pentru care Pk=n-1. Daca tabloul T nu are toate elementele distincte, pentru crearea tabloului P se face modificarea:
De exemplu:
Problema prezinta interes în cazul în care în locul tabloului T avem un fisier cu tip. Sortarea fisierului în raport cu o cheie (unul din câmpurile articolelor fisierului) revine la creearea unui fisier index care reprezinta un fisier de întregi (echivalent tabloului x), în care fiecare element xI da pozitia celui de.al i.lea element din fisierul sortat în fisierul initial. · Sa se defineasca o functie, care primind ca parametru un fisier binar, creeaza un fisier index în raport cu o cheie. · Sa se defineasca o functie care primind ca parametri un fisier si un fisier index asociat, afiseaza articolele fisierului sortate în raport cu indexul dat.
6. Se da un fisier text. a) Sa se determine numarul de linii din fisier. b) Sa se creeze un nou fisier cu liniile din primul, aparând în ordine inversa. c) Pe baza fisierului initial, sa se creeze un fisier de caractere, în care nu mai apar caracterele de sfârsit de linie, iar fiecare linie este precedata de lungimea ei (un octet) d) Se da un fisier de întregi reprezentând numere de linii din fisierul initial. Sa se afiseze la imprimanta liniile din fisier în ordinea precizata de fisierul de întregi.
7. Fisierul text prog.c reprezinta un program sursa C. Sa se copieze acest fisier la iesirea standard suprimând toate comentariile.
8. Se considera fisierul abonati.dat cu articole structuri având câmpurile: · Nume - un sir de 20 de caractere · Adresa - un sir de 30 de caractere · Data_expirarii - o structura cu câmpurile an, luna, zi. Consideram ca data curenta se introduce de la tastatura. Sa se actualizeze fisierul de abonati, stergând pe aceia al caror abonament a expirat la data curenta. Actualizarea se face creind un nou fisier în care se trec numai abonatii al caror abonament nu a expirat si care la sfârsit va primi numele fisierului initial. Se va defini si folosi o functie care compara doua date (d1 si d2) si întoarce 1 , daca d1 este înaintea lui d2, si 0 în caz contrar.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||