Fisiere relative - ATP PDF

Title Fisiere relative - ATP
Course Algoritmi si tehnici de programare
Institution Academia de Studii Economice din București
Pages 7
File Size 221 KB
File Type PDF
Total Downloads 139
Total Views 281

Summary

Exemple de operații cu fișiere binare de date organizate relativÎn exemplele următoare se lucrează cu un fișier binar de date organizat relativ care conține informații despre studențiiunei facultăți. Informațiile stocate sînt: număr matricol ( int ), nume complet (șir 29 caractere), CNP (șir 13 cara...


Description

Exemple de operații cu fișiere binare de date organizate relativ În exemplele următoare se lucrează cu un fișier binar de date organizat relativ care conține informații despre studenții unei facultăți. Informațiile stocate sînt: număr matricol (int), nume complet (șir 29 caractere), CNP (șir 13 caractere), an de studiu (int), grupa (int), un vector cu 20 de note (întreg pe 1 octet, fără semn). Pentru vectorul de note se folosește următoarea convenție: fiecărei materii îi corespunde o poziție fixă (de exemplu, nota la ATP se află pe poziția 7); valorile 1-10 constituie note, valoarea 0 are semnificația „încă nu e disponibilă o notă”. Numărul matricol are rol de cheie relativă. Domeniul de valori pentru numărul matricol este 1000-9999 (valoarea maximă ar putea fi depășită la nevoie, dacă sînt mai mult de 9000 studenți înscriși). Pentru a evita irosirea unui spațiu de 1000 articole lăsate neutilizate la începutul fișierului, se translatează domeniul cheilor către domeniul numerelor relative ale articolelor, scăzînd valoarea minimă a cheii (1000) din fiecare cheie. În acest fel, cheii 1000 îi corespunde articolul cu numărul relativ 0 etc. Structura fizică a articolelor se obține adăugînd la structura logică un cîmp cu rolul de indicator de stare, cu valorile 1 (articol valid) sau 0 (spațiu liber).

Crearea și popularea unui fișier relativ În condițiile actuale, preformarea nu este o operație necesară, nefiind implementată în exemplul de mai jos. Popularea se poate realiza în două versiuni: -

interactiv, cu preluarea datelor de la tastatură. Această variantă este incomodă pentru utilizator, dar singura posibilă dacă datele sînt preluate din documente fizice.

-

automat, cu preluarea datelor dintr-o sursă electronică. Această variantă este mai comodă și mult mai rapidă, dar poate fi utilizată doar dacă există o astfel de sursă de date. Un posibil exemplu este un fișier text cu datele studenților, exportat din altă aplicație.

Exemplul următor realizează popularea automată, cu preluarea datelor dintr-un fișier text (Input.txt) aflat în directorul curent, prin reasocierea fișierului stdin. Fișierul input.txt conține date corecte și complete, fără chei duplicat. Secvența următoare ilustrează modul în care sînt memorate datele în fișierul Input.txt (două grupuri de date, pentru 2 studenți, în ordinea: număr matricol, nume, CNP, an, grupa, note): 5324 Vlad-47 6481394568036 2 1003 4 8 10 0 3 4101 Dana-24 1899434280228 1 1004 1 4 5 3 6

4

2

9 10

2

2

1

1

8

0 10

4

7 10

2 10

7

5

2

4

2

7

3

3 10

4

3

8

1

8

Dacă se dorește popularea interactivă, trebuie făcute următoarele modificări: -

se elimină reasocierea fișierului stdin (apelul freopen("Input.txt", "r", stdin); )

-

se activează toate apelurile funcției printf, prin eliminarea marcatorilor de comentarii.

Popularea constituie de fapt o adăugare de articole, diferența între cele două operații fiind dată de factori exteriori (cantitatea de date care se adaugă, adăugarea se face de obicei interactiv). Dacă se dorește adăugare de date într-un fișier existent, trebuie făcute următoarele modificări: -

modul de deschidere pentru fișierul relativ devine "rb+"

-

nu se face preformarea fișierului.

#define _CRT_SECURE_NO_WARNINGS #include #include typedef struct { int nrm; char nume[30]; char CNP[14]; int an; int grupa; unsigned char note[20]; int is; }STUDENT;

//cheie relativa, de la 1000 ->

//indicator de stare

//numar de articole fizice din fisier //I: f - fisier, dim - dimensiune 1 articol //E: nrart - numar de articole fizice int nr_articole(FILE* f, int dim) { long c; int nr; c = ftell(f); fseek(f, 0, 2); nr = ftell(f) / dim; fseek(f, c, 0); return nr; } //se face translatie de la domeniul cheilor (numere matricole 1000->) // la domeniul numerelor relative ale articolelor (0 ->) scazind 1000 void main() { char numefr[30]; FILE* f; STUDENT x; int cheie,i,DIM; printf("Nume fisier relativ nou: "); gets_s(numefr); f = fopen(numefr, "wb+"); //"rb+" pentru adaugare art. in fis. existent //preformare, optional la creare si populare. nu se face la adaugare freopen("Input.txt", "r", stdin); //printf("Numar matricol: "); scanf("%d", &cheie); while (!feof(stdin)) { //prelucrare cheie //verificare 1: exista pozitia dorita in fisier? // daca nu, se extinde fisierul DIM = nr_articole(f, sizeof(STUDENT)); if (cheie - 1000 >= DIM) { //extindere fisier fseek(f, 0, 2); x.is = 0; for (i = DIM; i

int crt, i; printf("Nume fisier de consultat: "); gets_s(numefr); f = fopen(numefr, "rb"); if (!f) printf("\nNu se poate deschide fisierul %s", numefr); else { printf("\nNume fisier text: "); gets_s(numeft); g = fopen(numeft, "w"); fprintf(g,"\t\tLista cu toti studentii"); fprintf(g,"\n\nCrt. Nrm. %-30s %-14s An Grupa Note", "Nume", "CNP"); crt = 0; //prelucrare cu fisier conducator f. articol preluat din f: x //citire primul articol fread(&x, sizeof(STUDENT), 1, f); while (!feof(f)) { if (x.is == 1) //daca e articol valid { //prelucrare fprintf(g,"\n%4d %4d %-30s %-14s %2d %5d ", ++crt, x.nrm, x.nume, x.CNP, x.an, x.grupa); for (i = 0; i < 20; i++) fprintf(g, "%2d ", x.note[i]); } //incercare de citire a urmatorului articol fread(&x, sizeof(STUDENT), 1, f); } fclose(f); fclose(g); printf("\n\nLista se afla in fisierul %s" , numeft); } printf("\n\nGata, apasa o tasta..."); _getch(); }

Fragmentul următor ilustrează aspectul listei generate: Lista cu toti studentii Crt. 1 2 3 4 5 6 7 8

Nrm. 1017 1074 1077 1178 1284 1361 1395 1544

Nume Ionut-26 Adina-26 Cristian-27 Alexandru-58 Bianca-32 Ionut-94 Vlad-80 Tudor-83

CNP 4664996409422 7761799800065 3000657130798 0969375727977 9800540700885 5557659365282 8522291784109 5879585931468

An Grupa Note 1 1017 0 7 3 0 3 1012 6 10 10 1 1 1015 5 3 2 3 2 1005 8 8 4 4 1 1003 2 8 10 1 3 1008 6 4 6 6 2 1014 7 6 2 10 3 1002 7 7 9 3

0 6 3 7 8 6 3 3

5 6 2 9 5 9 5 6 4 10 10 7 7 10 2 8 9 2 7 10 8 6 8 1 1 2 0 7 8 6 6 1 3 3 1 7 10 0 2 9 8 6 7 0 7 7 10 7 10 5 10 1 0 0 10 4

5 4 5 8 3 0 6 3

5 1 1 5 1 1 0 8 1 1 8 1 2 9 2 3 4 6 6 2 5 8 10 6 9 6 1 10 5 3 2 8 2 9 6 9 6 10 10 4 4 7 7 6 10 5 4 10 2 4 3 8 2 10 0 7

Operații în acces direct, pe baza cheii Toate operațiile în acces direct (consultare, modificare, ștergere) se fac pe baza valorii cheii. Operația de ștergere a unui articol se realizează la nivel logic, prin modificare indicatorului de stare din 1 în 0, deci urmează algoritmul pentru modificare. Modificarea unui articol presupune întîi regăsirea lui, deci o operație de consultare în acces direct. În exemplul următor este implementată operația de consultare în acces direct, la care sînt adăugate două secvențe de prelucrări pentru modificare, respectiv ștergere articol. În funcție de scopul dorit, se poate elimina una (se dorește modificare sau ștergere) sau ambele secvențe (se dorește consultare).

Enunțurile implementate în exemplul următor sînt: -

vizualizarea notei la ATP pentru studenții ale căror numere matricole sînt introduse de la tastatură. modificarea notei la ATP pentru studenții ale căror numere matricole sînt introduse de la tastatură. exmatricularea studenților ale căror numere matricole sînt introduse de la tastatură.

#define _CRT_SECURE_NO_WARNINGS #include #include typedef struct { int nrm; char nume[30]; char CNP[14]; int an; int grupa; unsigned char note[20]; int is; }STUDENT;

//cheie relativa, de la 1000 ->

//numar de articole fizice din fisier //I: f - fisier, dim - dimensiune 1 articol //E: nrart - numar de articole fizice int nr_articole(FILE* f, int dim) { long c; int nr; c = ftell(f); fseek(f, 0, 2); nr = ftell(f) / dim; fseek(f, c, 0); return nr; } void main() { char numefr[30]; FILE* f; int cheie, DIM; unsigned char var; STUDENT x; printf("Nume fisier relativ: "); gets_s(numefr); f = fopen(numefr, "rb+"); if (!f) printf("\nFisierul nu poate fi deschis"); else { DIM = nr_articole(f, sizeof(STUDENT)); //prelucrare cu fisier conducator stdin. articol citit din stdin: cheie //citire prima cheie printf("\nNumar matricol: "); scanf("%d", &cheie); while (!feof(stdin)) { //prelucrare cheie //verificare 1: exista positia dorita? if (cheie - 1000 >= DIM) printf("\nNu exista student cu numarul matricol %d", cheie); else { //verificare 2: pozitia dorita este ocupata? fseek(f, (cheie - 1000) * sizeof(STUDENT), 0); fread(&x, sizeof(STUDENT), 1, f);

if (x.is == 0) printf("\nCheie invalida"); else { //vizualizare printf("\nNume: %s, Grupa: %d, ATP: %d", x.nume, x.grupa, x.note[7]); //modificare printf("\nNota ATP (0 - nu se schimba): "); scanf("%hhi", &var); if (var == 0) printf("\nModificare abandonata"); else { x.note[7] = var; fseek(f, (cheie - 1000) * sizeof(STUDENT), 0); fwrite(&x, sizeof(STUDENT), 1, f); fseek(f, 0, 1); } //sfirsit modificare //stergere /*printf("\nSe exmatriculeaza? (1 - da, 0 - nu): "); scanf("%hhi", &var); if (var != 1) printf("\nExmatriculare abandonata"); else { x.is=0; fseek(f, (cheie - 1000) * sizeof(STUDENT), 0); fwrite(&x, sizeof(STUDENT), 1, f); fseek(f, 0, 1); }*/ //sfirsit stergere } } //citire cheie urmatoare printf("\nNumar matricol (CTRL+Z): "); scanf("%d", &cheie); } fclose(f); } printf("\n\nGata, apasa o tasta..."); _getch(); }

Teme 1. O organizație păstrează datele privind obiectele de inventar deținute într-un fișier binar organizat relativ, cu articole avînd structura fizică descrisă mai jos. Cheia relativă este numărul de inventar, care are valori acordate secvențial obiectelor, începînd de la 1100. Număr de inventar int

Denumire obiect

Tip obiect

char[30]

char[20]

Data achiziției lună zi an int char char

Valoare

Nume gestionar

float

char[30]

Indicator de stare int

Implementați următoarele operații: a. b. c. d.

Crearea și popularea interactivă a fișierului. Generarea unei liste cu toate obiectele de inventar deținute (într-un fișier text). Diminuarea cu 10% a valorii de inventar pentru obiectele achiziționate înainte de un an dat de la tastatură. Eliminarea obiectelor ale căror numere de inventar se dau de la tastatură.

e. Generarea unei liste (într-un fișier text) cu obiectele de inventar cu valoare mai mare decît un prag dat de la tastatură.

2. Alegeți un tip de entități pretabile la asocierea cu o cheie relativă. Stabiliți datele pe care vreți să le stocați pentru aceste entități și cheia relativă asociată. Definiți și implementați toate operațiile de gestiune necesare pentru un fișier binar organizat relativ cu date despre entitățile alese....


Similar Free PDFs