Documente Academic
Documente Profesional
Documente Cultură
aLl_fisiere2013
Tema: Elaborarea programelor pentru prelucrarea funcţiilor cu diverse
structuri şi fişiere în limbajul C.
Sarcina şi obiectivele:
1. să se analizeze principiile organizării şi gestiunii fişierelor în sistemele de operare şi procesarea fişierelor în
limbajul C, apoi şi să se analizeze algoritmii şi programele (declarări, utilizări, parcurgeri, salvare şi ştergeri).
Pentru aprofundarea şi rularea programelor în limbajul C să se elaboreze scenariile succinte de soluţionare cu
calculele de verificare şi explicaţii.
2. de studiat şi însuşit materialul teoretic prin lansarea exerciţiilor de antrenament şi verificări ale cunoştinţelor
(din indicaţiile acestea) şi să se elaboreze algoritmii şi, totodată, să organizeze calculele de verificare cu
explicaţii pentru evidenţierea esenţialului prelucrării fişierelor cu structuri de date în elaborarea modelelor
soluţiei. Toate observaţiile se înregistrează în raport;
3. să se preia de la profesor varianta (6. Variante pentru lucrul individual) şi să se elaboreze algoritmii şi şi
programul unde să organizeze antetul functiilor şi transmiterea functiei apelate adresele variabilelor cu
calculele de verificare şi cu explicaţii la prelucrarea fişierelor.
4. să se analizeze listingurile din compartimentul 4,5 (4. Exemple de verificare a cunoştinţelor însuşite; 5.
Exemplu model pentru evidenţierea principiilor de elaborare şi prelucrarea grafului cu funcţii şi diverse SD.
De fragmentat și de ansamblat cu diverse posibilități.) corectitudinea și rezultatele obținute cu argumentări.)
5. în baza funcţiilor de timp şi dată din fişierul header time.h apreciaţi timpul definit de sistem şi timpul
execuţiei programului în secunde pentru ambele cazuri (tradiţional şi cu pointeri) şi să se descrie scenariile şi
principiile de algoritmizare si rezolvare ale problemei în baza diferitor modele de SD complexe,
implementând subprograme în C;
6. în raport să se reflecte toate exemplele efectuate cu analize a tehnicii programării eficiente cu argumentări şi
comentarii, incluzând fişierele cu teste de verificare şi vizualizări ale rezultatelor.
Consideraţii teoretice:
1. Organizarea şi gestiunea fişierelor în sistemele de operare (SO).
Tratarea informaţiilor cere prezenţa lor în memorie în timpul execuţiei programului dat. Dar în majoritatea
cazurilor trebuie neapărat ca aceste informaţii să fie conservate de o manieră durabilă .Ca exemplu elementar , se
poate de citat informaţiile relative ale clienţilor unor întreprinderi. De aceleaşi date (cod, client, numele clientului,
adresa ,cifra de afaceri ), sunt cele mai des exploatate pe o perioadă lungă de timp. Ele trebuie să fie rechemate la
moment şi în particular. În acest scop ele sunt scrise într-un fişier, care este stocat pe o memorie masivă (discul
magnetic) şi accesibil programului, manipulând informaţiile.
Un fişier nu este altceva decât o mulţime mai mult sau mai puţin importante de date, conservate pe un
oarecare suport.
Fişierele pot fi cu acces direct (stocate pe disc) sau cu acces secvenţial (stocate pe bandă). Numele fişierelor
are structura: numefişer.extensia.
SO UNIX suportă aşa-numitele fişiere conductă ("pipes") care pot fi deschise de două procese pentru a
stabili un canal de comunicaţie interproces.
Fişierele sunt împărţite în tipuri diferite în funcţie de utilizarea lor. Diferenţierea tipurilor se face prin
extensii diferite a numelui fişierului. De exemplu:
FILE.C; FILE.CPP: program - sursă în C/C++;
FILE.PAS: program - sursă în Pascal;
FILE.FTN: program - sursă în Fortran;
FILE.OBJ: fişier - obiect, rezultat în urma compilării;
FILE.BIN: program executabil (în mod binar);
FILE.DAT: fişier de date, etc.
Uneori extensia este o simplă convenţie, sistemul de operare neţinând cont de aceasta.
1.1. ORGANIZAREA SISTEMELOR DE FIŞIERE
Organizarea fişierelor este specifică fiecărui sistem de operare.
În sistemul de operare UNIX, fişierele sunt organizate în arborele unic al fişierelor, existând o singura rădăcină.
Acest sistem de operare tratează egal fişiere sau dispozitive.
În sistemul de operare MS-DOS există nume de dispozitive (ex.: A,B,C). Dispozitivele de disc permit organizări
arborescente.
Simplificarea accesului a dus la apariţia conceptului de directoare. Un director este un fişier de indicare a localizării
celorlalte fişiere. Un director e organizat pe înregistrări (articole), câte una pentru fiecare fişier; fiecare articol conţine
informaţii despre fişier ca: nume, tip, dimensiune, timp etc. La CP/M directorul conţinea şi numerele de ordine ale blocurilor
alocate. Fişierul este localizat prin cale (path), care precizează locul în arbore.
1.2 GESTIUNEA SPAŢIULUI PE DISC
Gestiunea spaţiului pe disc nu se face pe sectoare fizice; există unităţi de alocare, fiecare unitate conţinând un
multiplu de sectoare fizice, oferind flexibilitate la schimbarea dispozitivului. Contabilizarea sectoarelor ocupate se
realizează in doua moduri:
1. lista înlănţuită, care conţine unităţi de 16 biţi pe care se înregistrează numărul de blocuri ocupate succesiv;
2. bit-map, în care primul bit are semnificaţia de ocupat / neocupat.
Sistemul MS-DOS foloseşte listele înlănţuite (fiecare bloc conţine doi octeţi ce reprezintă un pointer către
următorul bloc din lanţ), ceea ce permite întreţinerea rapidă la eliberare/alocare spaţii pentru fişiere. La ştergere,
dispar înregistrările de 16 biţi corespunzătoare blocurilor fişierelor. La alocare, se ocupa în măsura găsirii spaţiilor
neînregistrate în FAT.
Sistemul UNIX înlatură dezavantajul fişierelor mari cu unităţi multe de alocare, care necesită un FAT mare in
sistemul MS-DOS astfel: se utilizează gestiunea spaţiului pe disc cu I-noduri (Index-nod). Fiecare fişier are un I-nod
(indiferent de dimensiunea fişierului respectiv).
1.3 ORGANIZAREA FIŞIERELOR ÎN UNIX
Spaţiul de pe un disc cu sistem de operare UNIX este împărţit astfel:
- Boot
- Superbloc:-volumul;
- nr. blocuri libere;
- tabelul blocurilor libere;
- index la primul bloc liber din tabela blocurilor libere;
- dimensiunea zonei de I-noduri;
- număr de I-noduri libere;
- index la primul I-nod liber;
- câmpuri cheie.
- I-noduri
- Date
- Swap.
Superblocul este prezent în memorie.
1.3.1 FIŞIERE PARTAJATE
Mai mulţi utilizatori care lucrează împreună la o aplicaţie au nevoie să exploateze în comun fişiere comune; este
convenabil ca un astfel de fişier să apară simultan în directoare de lucru diferite aparţinând unor utilizatori diferiţi.
Director rădăcină
A B C
A B B B C C
B C C
? C C C
Fişier partajat
numele fişierului
tipul fişierului
ENTRY lungimea
posesor
ENTRY
informaţie de protecţie
ENTRY data şi ora creerii
data şi ora ultimei modificări
ENTRY
lista de blocuri utilizate
Cel mai simplu sistem este constituit dintr-un singur director care conţine toate fişierele (intările lor) pentru toţi
userii. Dar dacă mai mulţi useri încearcă să acceseze în acelaşi timp un fişier va apărea un conflict. Această metodă este
folosită în sistemele mai vechi.
O altă metodă este să existe câte un director pentru fiecare user. Acest model elimină conflictele dar rămâne un
neajuns: utilizatorii nu îşi pot organiza fişierele în grupuri.
Un sistem flexibil este acela în care fiecare utilizator poate avea oricâte directoare are nevoie.
Root Root
directory directory
a b c a b c
a a a b c c
Pentru un astfel de sistem de fişiere organizat sub forma unui arbore, există două metode de a identifica fişierele:
1. Fiecare fişier primeşte un nume de cale absolută (absolute path name) care constă într-o cale din directorul radacină.
2. Alt mod este precizarea numelui căii relative (relativ path name).
Acest procedeu este folosit în conjuncţie cu conceptul de director de lucru (director curent). Un utilizator poate desemna
un director curent şi în acest caz numele căilor nu încep de la rădăcină, ci sunt relative la directorul de lucru.
1.5 STOCAREA FIŞIERELOR
Un fişier este memorat pe un anumit mediu într-o secvenţă de blocuri care trebuie gestionată de sistem. Stocarea
consecutivă a acestor blocuri nu este un lucru fezabil.
O metodă realizabilă este stocarea blocurilor într-o listă înlănţuită. Există două dezavantaje:
1. Nmărul octeţilor de date nu mai este o putere a lui 2;
2. Accesul aleator este scump de implementat.
Totuşi ideea de reprezentare a fişierelor ca o listă înlînăuită s-a păstrat, însă pointerii sunt stocaţi în memorie. Se asociază
fiecărui disc o tabelă de alocare de fişiere (FAT). FAT-ul are o intrare pentru fiecare bloc de pe disc. Intrarea directorului
pentru fiecare fişier primeşte numărul primului bloc de pe disc al fişierului. Mai departe slotul din FAT corespunzător fiecărui
bloc conţine numărul blocului următor.
Acest model a fost utilizat pe discuri floppy pentru discuri floppy de 360 k cu dimensiunea blocului de 1 k.
Numărul de identificare al blocului este de 12 biţi existând deci 480 de octeţi în FAT.
Principala problemă a FAT-ului este că pointerii tuturor fişierelor de pe întreg discul sunt mixate aleator în
această tabelă. Deci e nevoie de întreg FAT-ul chiar dacă un singur fişier este deschis. O metodă mai bună ar fi păstrarea mai
multor liste de blocuri pentru fişiere diferite în locuri diferite. Această metodă este folosită de UNIX, unde fiecare fişier are
asociată o mică tabelă (pe disc) numită I-node. Fiecare I-nod conţine pointeri către 10 blocuri de date de pe disc plus încă 3
pointeri indirecţi.
spre blocuri
de date
Pentru primele 10 blocuri din fişier adresele sunt trecute chiar în i-nod, fiind foarte uşor de accesat. Pentru fişiere mai
lungi de 10 blocuri se alocă un bloc de pointeri pe disc ce va fi accesat prin intermediul primului pointer indirect. Pointerul
dublu către blocuri de pointeri ce pointează la blocuri de pointeri către blocuri de date. Pointerul triplu acţionează după un
raţionament similar. Doar cu ajutorul pointerului dublu pot fi accesaţi 64 kblocuri.
Esenţial la acest sistem este faptul că blocurile de pointeri indirecţi sunt utilizate (încărcate în memorie) doar dacă este
necesar, făcându-se cel mult trei referinţe la disc oricât de lung ar fi fişierul.
1.6 STRUCTURA DIRECTOARELOR
Înainte ca un fişier să poată fi citit el trebuie deschis de către sistemul de operare care preia de la utilizator numele căii
pentru a putea identifica blocurile de pe disc alocate fişierului.
În sistemul CP/M exista doar un singur director. Pointerii către blocurile de date de pe disc sunt stocaţi chiar în intrarea
directorului.
16
1 8 3 1 2 1
File name ... ...
8 3 1 10 2 2 2 44
File name Reserved Time Date Size
i-nod number
Când se deschide un fişier sistemul de gestiune trebuie să găsească numele fişierului şi blocurile de pe disc. Ex.:
Fie calea /usr/ast/mbox. Mai întâi se localizează directorul rădăcină, apoi se identifică prima componentă a căii căutând i-
nodul fişierului /usr. Din acest i-nod sistemul de fişiere localizează directorul pentru /usr şi caută în el componenta următoare
ast. Din acest i-nod şi identifică similar mbox. I-nodul acestui fişier este încărcat în memorie şi reţinut până când fişierul se
închide.
1 . mod 6 . mod 26 .
1 .. m\rime 1 .. m\rime 6 ..
4 bin data 26 ast data 17 src
6 usr 132 51 jim 406 60 mbox
14 lib
8 tmp
Identificarea fişierelor prin precizarea numelui căii relative se face similar, dar procesul de căutare începe din directorul
de lucru.
1.7 VERIFICAREA CORECTITUDINII GESTIONăRII FIŞIERELOR
Multe sisteme de operare citesc blocuri, le modifică iar apoi le scriu; dacă sistemul cade înainte ca toate blocurile
modificate să fie scrise, sistemul de gestiune a fişierelor poate rămâne într-o stare nedefinită. Această problemă este cu atât
mai gravă cu cât blocurile care nu au fost scrise sunt I-noduri, blocuri de directoare sau blocuri conţinând liste libere.
Pentru a rezolva această problemă multe calculatoare dispun de un program utilitar care verifică soliditatea gestiunii
fişierelor: programul este rulat ori de câte ori se execută secvenţa de boot, mai ales după o cădere a sistemului respectiv.
Probleme ce pot apare: blocuri lipsă, caz în care programul de verificare doar le adaugă în lista blocurilor libere; blocuri
alocate dublu în lista de blocuri libere (această problemă apare doar dacă se lucrează cu lista; cu bit-map este imposibil), în
acest caz programul de verificare reconstruind lista blocurilor libere; sau acelaşi bloc de date este prezent în două sau mai
multe fişiere. Dacă oricare din aceste fişiere este şters, blocul respectiv va fi pus în lista blocurilor libere, ajungându-se la
situaţia în care un acelaşi bloc este simultan şi liber şi ocupat; dacă ambele fişiere sunt şterse, blocul va fi trecut de două ori
în lista blocurilor libere.Verificarea se poate face în două moduri: pe blocuri şi pe fişiere.
La verificarea pe bloc programul construieşte o tabelă cu doi contori per bloc, fiecare contor fiind iniţializat cu 0. Primul
contor urmăreşte de câte ori un bloc este prezent într-un fişier; al doilea înregistrează cât de adesea este prezent în lista
blocurilor libere (sau în bit-map-ul blocurilor libere). După aceasta, programul citeşte toate I-nodurile; pornind de la un
I-nod programul poate construi o listă cu toate numerele blocurilor utilizate ce corespund fişierului. Pe măsură ce fiecare
număr de bloc este citit, primul contor este incrementat; programul examinează apoi lista blocurilor libere sau bit-map-ul
pentru a găsi toate blocurile care nu sunt utilizate. Fiecare apariţie a blocului în lista blocurilor libere sau bit-map este
contorizată în cel de-al doilea contor.
Scierea
Pointer
FILE Citirea
Program tampon
A B C D E F G H
4. /* Problema 1 set 4 : Program pentru crearea unui fisier binar, avand articole structuri cu urmatoarele campuri:
-nume depunator (sir de maxim 30 de caractere)
-data depunerii (o structura avand campurile intregi: zi,luna,an)
-suma depusa (o valoare reala).
Articolele sunt grupate pe zile in ordine cronologica.
Datele se introduc de la consola, fiecare pe 3 linii. */
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<stdlib.h>
#define MAX 3
typedef struct { int zi; int luna; int an; } DATA;
typedef struct { unsigned char nume[30]; DATA dat; int sum; } CLIENT;
void main()
{ CLIENT bd[MAX]; int i; FILE *baza; printf("\n Introduceti datele persoanelor ");
for(i=0;i<MAX;i++) { printf("\n====================================");
printf("\n Nume : "); scanf("%s",&bd[i].nume);
printf("\n Data : "); scanf("%d-%d-%d",&bd[i].dat.zi,&bd[i].dat.luna,&bd[i].dat.an);
printf("\n Suma : "); scanf("%d",&bd[i].sum); };
baza=fopen("date.dat","w"); fwrite( bd, sizeof( CLIENT ), MAX, baza ); fclose( baza ); }
5. /* Program care, folosind fisierul creat in problema 1, calculeaza si afiseaza:
- -suma maxima depusa, impreuna cu data si numele depunatorului
- -numarul depunerilor din fiecare zi, si suma totala depusa in fiecare zi, tinand cont ca tranzactiile dintr-o zi sunt contigue
in fisier. */
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<stdlib.h>
#define MAX 3
typedef struct { int zi; int luna; int an; } DATA;
typedef struct { unsigned char nume[30]; DATA dat; int sum; } CLIENT;
void main() { CLIENT bd[MAX]; int j,sm,i,smax,ni; FILE *baza;
baza=fopen("date.dat","r"); fread( bd, sizeof( CLIENT ), MAX, baza ); fclose( baza ); smax=0;
for(i=0;i<MAX;i++) { if (smax<bd[i].sum) { smax=bd[i].sum; ni=i; } }
printf("\n %s , %d-%d-%d , %d \n",bd[ni].nume, bd[ni].dat.zi, bd[ni].dat.luna, bd[ni].dat.an, bd[ni].sum);
j=1; sm=bd[0].sum;
for (i=1;i<MAX;i++) {
if (bd[i].dat.zi==bd[i-1].dat.zi && bd[i].dat.luna==bd[i-1].dat.luna && bd[i].dat.an==bd[i-1].dat.an)
{ j=j+1; sm=sm+bd[i].sum; } else {
printf(" \n Nr. depuneri din data %d-%d-%d = %d ; Suma depusa = %d ",bd[i-1].dat.zi,bd[i-1].dat.luna,bd[i-1].dat.an,j,sm);
j=1; sm=bd[i].sum; } }
printf(" \n Nr. depuneri din data %d-%d-%d = %d ; Suma depusa = %d ",bd[i-1].dat.zi,bd[i-1].dat.luna,bd[i-1].dat.an,j,sm);
printf("\n \n"); }
6. / Program, care folosind fisierul creat in problema 5, actualizeaza acest fisier prin adaugarea dobanzii, la data curenta. Se
precizeaza urmatoarele date: -data curenta la care se calculeaza dobanda (an,luna,zi) -dobanda anuala. Se va folosi o functie
care determina numarul de zile dintre data depunerii si data curenta, pentru a calcula dobanda cuvenita.*/
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<stdlib.h>
#define MAX 3
typedef struct { int zi; int luna; int an; } DATA;
typedef struct { unsigned char nume[30]; DATA dat; int sum; } CLIENT;
int nrzile(int a1,int a2,int a3) { int y,nr; nr=0;
for(y=1;y<a3;y++) if (y % 4==0) nr=nr+365; else nr=nr+364;
for(y=1;y<a2;y++); if (y%2==0) if (y!=2) nr=nr+30;
else nr=nr+28; else nr=nr+31; nr=nr+a1; return(nr); }
void main() { CLIENT bd[MAX]; int i,n1,n2,n3,dobanda; FILE *baza;
baza=fopen("date.dat","r"); fread( bd, sizeof( CLIENT ), MAX, baza ); fclose( baza );
printf(" Introduceti data curenta : "); scanf("%d-%d-%d",&n1,&n2,&n3);
printf("\n Introduceti dobanda : "); scanf("%d",&dobanda);
for (i=0;i<MAX;i++) { bd[i].sum=bd[i].sum+(nrzile(n1,n2,n3)-nrzile(bd[i].dat.zi,bd[i].dat.luna,bd[i].dat.an))*dobanda; }
baza=fopen("date.dat","w"); fwrite( bd, sizeof( CLIENT ), MAX, baza ); fclose( baza );}
4. Exemple de verificare a cunoştinţelor însuşite: în listingul programelor de mai jos verificaţi
corectitudinea, scopul şi rezultatele:
1. Listingul programului:
#include<conio.h>
#include<stdio.h>
#include<string.h>
void main() {clrscr(); int i,n;
FILE *f;
f=fopen("d:\\input.txt","r");
char *s,**s1,*aux;
fgets(s,1000,f);
for(i=0,n=0;i<strlen(s);i++) if((s[i]=='.')||(s[i]=='!')) n++;
s1[0]=strtok(s,".!");
for(i=1;i<n;i++) s1[i]=strtok(NULL,".!");
aux=s1[0]; s1[0]=s1[2]; s1[2]=aux;
for(i=0;i<n;i++)printf("%s. ",s1[i]);
fclose(f);
getch();
}
2. Listingul programului:
#include<stdio.h>
#include<conio.h>
void main() {clrscr();
FILE *f;
int i,x;
f=fopen("e:\\numbers.txt","a");
printf("\n Introduceti 5 numere:\n");
for(i=0;i<5;i++)
{scanf("%d",&x);
fprintf(f,"%d\n",x);
}
fclose(f);
getch();
}
3. Listingul programului:
#include<conio.h>
#include<stdio.h>
void main() {clrscr();
FILE *f;
int i,x,S=0;
f=fopen("file.txt","w+");
printf("\n introduceti zece numere intregi \n");
for(i=0;i<10;i++) { scanf("%d",&x); fprintf(f,"%d ",x); } rewind(f);
while(!feof(f)) {
fscanf(f,"%d",&x);
if(!feof(f))
S+=x; }
printf("S=%i",S); getch(); fclose(f); }
4. Listingul programului:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<dos.h>
void main() {clrscr();
struct dosdate_t d;
struct dostime_t t; printf(" \n De la inceputul erei noastre au trecut: \n "); _dos_getdate(&d);
printf("\n %d veacuri %d ani %d luni %d zile ",d.year/100,d.year,d.month,d.day); _dos_gettime(&t);
printf(" %2d:%02d:%02d.%02d\n", t.hour, t.minute,t.second, t.hsecond); getch(); }
5. Listingul programului:
#include <string.h>
#include <stdio.h>
int main(void){ FILE *fp;
char buf[11] = "0123456789"; /* create a file containing 10 bytes */
fp = fopen("DUMMY.FIL", "w"); fwrite(&buf, strlen(buf), 1, fp);
/* close the file */ fclose(fp); getchar(); return 0; }
6. Listingul programului:
#include <stdio.h>
#include <ctype.h>
#include <mem.h>
char q[250]; int g[26]; int k[26]; int len=0;
int main()
{ FILE *f; int ch,i; long kol; f=fopen("input.txt","r");
while((ch=fgetc(f))!='\n') { if(isalpha(ch)) { g[ch-'A']++; len++; } }
i=0; kol=0; if(len>0)
while((ch=fgetc(f))!=EOF) { if(isalpha(ch))
{ if(q[i]) k[q[i]-'A']--; q[i]=ch; k[ch-'A']++; i=(i+1)%len; if(memcmp(g,k,sizeof(g))==0) kol++; } }
fclose(f); f=fopen("output.txt","w"); fprintf(f,"%ld\n",kol); fclose(f); return 0; }
7. Listingul programului:
#include<stdio.h>
#include<conio.h>
main()
{ int acc; char nume[10]; float balanta;
FILE *cfPtr; clrscr();
if ((cfPtr= fopen("clientii.txt","w"))==NULL) printf("Failul nu poate fi deschis\n");
else {printf("introdu banii,numele,si balanta\n"); printf("introdu sf. daca m.\n"); printf("?");
scanf("%d%s%f",&acc,nume,&balanta);
while(!feof(stdin)){ fprintf(cfPtr,"%d%s%.2f\n", acc,nume,balanta); printf("?");
scanf("%d%s%f",&acc,nume,&balanta); } fclose(cfPtr); } return 0;
}
8. Listingul programului:
#include <conio.h>
#include <stdio.h>
#include <string.h>
struct regest{ char name[20]; int ani; }; regest cat[2]; FILE *f1,*f2;
void init_f()
{int num=sizeof(cat)/sizeof(cat[0]); f1 = fopen("f1","w"); f2 = fopen("f2","w"); clrscr();
printf(" Introduceti %d de inregistrari.\n",num+1);
for(int i=0;i<=num;i++) { printf("Inregistr. nr.%d \n",i); scanf("%s %d", &cat[i].name, &cat[i].ani);
fprintf(f1,"%s ",cat[i].name); fprintf(f2,"%d ",cat[i].ani); };
// fflush(f1); fflush(f2);
fclose(f1); fclose(f2); }
void init(){ int i=0;
while (!feof(f1)) { fscanf(f1,"%s ",&cat[i].name); fscanf(f2,"%d ",&cat[i].ani); i++; } }
void afish(){ int num=sizeof(cat)/sizeof(cat[0]); printf("Afisarea continutului catalogului\n");
for (int i=0;i<=num;i++) printf("%s %d\n",cat[i].name,cat[i].ani); }
int num_lit(){ int num=sizeof(cat)/sizeof(cat[0]); int len,min=strlen(cat[0].name);
for (int i=1; i<=num; i++) { len=strlen(cat[i].name); if (len<min) min=len; } return (min); }
void afish_min(int l)
{ int num=sizeof(cat)/sizeof(cat[0]);
for (int i=0;i<=num;i++) { if (strlen(cat[i].name)==l) printf("%s %d \n",cat[i].name,cat[i].ani); } }
void main(){ int lungimea; clrscr(); f1 = fopen("f1","r"); f2 = fopen("f2","r");
if (f1==NULL) {init_f();} else{init();}; lungimea = num_lit(); afish(); afish_min(lungimea);
fclose(f1); fclose(f2); getch(); }
9. Listingul programului:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main(){ clrscr(); FILE *fin; int x,w,d,y,max=0,min=0; int k,p,s; fin=fopen("ts.txt","r"); int a[20]; int i=0;
if (fin==NULL) { printf(" Eroare"); exit(1); }
while(!feof(fin)) { fscanf(fin,"%d",&y); a[++i]=y; printf("%d ",y); } fclose(fin); max=a[1];
{ for (k=1;k<=i;k++) if (max<a[k]) { max=a[k]; w=k;} } min=a[1];
{ for ( k=1;k<=i;k++) if (min>a[k]) { min=a[k]; s=k;} }
printf("\n Numarul maxim %d si num minim %d \n",max,min);
printf("\n Locul num maxim %d si num minim %d\n ",w,s);
for (k=w;k>=s; k--) printf("%d ",a[k]); getch(); }
10. Listingul programului:
#include <stdio.h>
#include <conio.h>
#define MIN_DISCOUNT .97
#define MAX_DISCOUNT .95
void main()
{ float frPrice, fbPrice; FILE *fin, *fout; fin = fopen("customer.dat", "r"); fout = fopen("billing.dat", "w");
if (fin == NULL) { printf("Fisierul CUSTOMER.DAT nu exista!"); getch(); return; }
while (fscanf(fin, "%f", &frPrice) != EOF) { if (frPrice < 100) fbPrice = frPrice * MIN_DISCOUNT;
else fbPrice = frPrice * MAX_DISCOUNT;
fprintf(fout, "Suma $%8.2f ", frPrice); printf("Suma $%8.2f ",frPrice); fprintf(fout, "cu rabat e $%8.2f\n", fbPrice);
printf("cu rabat e $%8.2f\n", fbPrice); } printf("\nDatele de mai sus au fost salvate");
printf(" in fisierul BILLING.DAT!"); getch(); }
11. Listingul programului:
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
typedef struct articol{ int camp1; char camp2[80]; unsigned char camp3; float camp4; };
int *p_int; int **p_mat; articol *p_art; int mat[3][3]={{1,2,3},{4,5,6},{7,8,9}};
articol art[1]={{100,"sir1",’a’,12.3},};
void main(){ clrscr(); p_int=(int *)malloc(sizeof(int)); *p_int=10; p_mat=(int**)malloc(3*sizeof(int*));
for(int i=0;i<3;i++) p_mat[i]=(int*)malloc(sizeof(int));
for(i=0;i<3;i++) for(int j=0;j<3;j++) p_mat[i][j]=mat[i][j]; p_art=(articol *)malloc(sizeof(articol));
p_art=art; printf("\nintregul este:...%d", *p_int); printf("\nmat[1][1] este:...%d",p_mat[1][1]);
printf("\ncamp 3 este:...%c",p_art->camp3); getch(); }
5. Exemplu model pentru evidenţierea principiilor de elaborare şi prelucrarea grafului cu funcţii şi
diverse SD. De fragmentat și de ansamblat cu diverse posibilități.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <alloc.h>
#include <ctype.h>
#include <string.h>
#include <graphics.h>
#include <math.h>
#define MAXARC 20
#define MINARC 2
#define MAXVIRF 20
#define MINVIRF 2
#define WINDX 40
#define WINDY 10
#define WINDCOLBK 9
#define WINDCOLFR 15
#define WINDCOLBKSEL 2
#define WINDCOLFRSEL 11
#define WINDCOLTITLE 14
#define WINDCOLFRAME 7
#define FEXTENSION ".grf"
#define MAXRADIUS 220
#define RADPERVIRF 20
#define VIRFRADIUS 10
#define PI M_PI
#define ORIGX 320
#define ORIGY 240
const char *MAIN_MENU[] =
{"$Meniu:","1 Graf nou ","2 Afisare ","3 Transformare ",
"6 Prelucrare ","4 Citire ","5 Salvare ","0 Iesire ",
"9 Despre program ",""};
const char *MENU_NEW[] =
{"$Graf nou:","1 Matrice de incedenta ","2 Matrice de adiacenta ",
"3 Lista de adiacenta ","0 Meniu precedent",""};
const char *MENU_SHOW1[] =
{"$Modul de afisare:","1 Mod text ","2 Mod grafic ",
"0 Meniu precedent ",""};
const char *MENU_SHOW2[] =
{"$Afisare:","1 Matrice de incedenta ","2 Matrice de adiacenta ",
"3 Lista de adiacenta ","0 Meniu precedent ",""};
const char *MENU_TRANS1[] =
{"$Indicati sursa:","1 Matrice de incedenta ",
"2 Matrice de adiacenta ","3 Lista de adiacenta ",
"0 Meniu precedent ",""};
const char *MENU_TRANS2[] =
{"$Indicati destinatia:","1 Matrice de incedenta ",
"2 Matrice de adiacenta ","3 Lista de adiacenta ",
"0 Meniu precedent ",""};
const char *MENU_SAVE[] =
{"$Salvare:","1 Matrice de incedenta ","2 Matrice de adiacenta ",
"3 Lista de adiacenta ","0 Meniu precedent ",""};
const char *MENU_EXIT[] =
{"$Doriti sa iesiti din program ?","1 DA ","0 NU ",""};
typedef struct LISTA {
int val;
LISTA *next;
};
LISTA **lista=NULL;
char **matr_inc=NULL,
**matr_adi=NULL,
tip_inc=-1, tip_adi=-1, tip_lista=-1, screen=1;
int virf=0, arce=0, radius; float alfa;
char graf_nou(void);
char afisare(char);
char afisare_sursa(void);
void afisare_text(char);
void afisare_matr_inc(void);
void afisare_matr_adi(void);
void afisare_lista(void);
char afisare_graf(char);
void afisare_graf_matr_inc(void);
void afisare_graf_matr_adi(void);
void afisare_graf_lista(void);
void transformare(void);
void citire(void);
char cit_matr_inc(FILE *, int, int, char);
char cit_matr_adi(FILE *, int, char);
char cit_lista(FILE *, int, char);
void salvare(void);
void sal_matr_inc(FILE *f);
void sal_matr_adi(FILE *f);
void sal_lista(FILE *f);
void iesire(void);
void trans_adi_inc(void);
void trans_inc_adi(void);
void trans_inc_lista(void);
void trans_lista_inc(void);
void trans_adi_lista(void);
void trans_lista_adi(void);
void prelucrare(void);
char control_graf(void);
void read_matr_adi(void);
void read_matr_inc(void);
void read_lista(void);
char **getmatr(int, int);
void freematr(char **, int);
LISTA **getlista(int);
LISTA *getlista_el(void);
void freelista(LISTA **,int);
void freelista_el(LISTA *);
int show_menu(const char **);
void draw_frame(char, char);
void about(void);
void Graph_Init(void);
void getcoord(int *,int *, int);
void drawvirf(int ,int ,int);
void joinvirf(int ,int ,char );
void main(void)
{start:
while (1) { if (screen) { window(1,1,80,25); textbackground(0); textcolor(WINDCOLFRAME); clrscr();
screen=0; draw_frame(WINDX,WINDY); }
switch (show_menu(MAIN_MENU)) {
case '1': graf_nou();break;
case '2': afisare_sursa();break;
case '3': transformare();break;
case '6': prelucrare();break;
case '4': citire();break;
case '5': salvare();break;
case '0': iesire();break;
case '9': about();break; }
} }
char graf_nou(void)
{ switch (show_menu(MENU_NEW)) {
case '1': read_matr_inc();break;
case '2': read_matr_adi();break;
case '3': read_lista();break;
case '0': return -1;
} return 0; }
char afisare(char tip)
{char ch;
do {
switch (ch=show_menu(MENU_SHOW1)) {
case '1': afisare_text(tip);break;
case '2': afisare_graf(tip);break;
case '0': return -1;
} } while (ch==-1); return 0; }
char afisare_sursa(void)
{ char ch;if (control_graf()==1) return 0;
do {
switch (ch=show_menu(MENU_SHOW2)) {
case '1': if (tip_inc==-1) ch=-1;break;
case '2': if (tip_adi==-1) ch=-1;break;
case '3': if (tip_lista==-1) ch=-1;break;
case '0': return -1;
}
if (ch==-1) {
cprintf("Nu este introdusa.");
getch();
}
else ch=afisare(ch);
} while (ch==-1); return 0; }
void afisare_text(char tip)
{switch (tip) {
case '1': afisare_matr_inc();break;
case '2': afisare_matr_adi();break;
case '3': afisare_lista();break;
} getch(); }
void afisare_matr_inc(void)
{int i,j; window(1,1,80,25); textbackground(0); clrscr(); textcolor(YELLOW);
cprintf("Matricea de incidenta."); draw_frame(virf*3+1,arce+2); textcolor(YELLOW);
for (i=0;i<arce;i++) {
for (j=0;j<virf;j++)
if (matr_inc[i][j]==1) cprintf(" 1 ");
else if (matr_inc[i][j]==0) cprintf(" 0 ");
else cprintf("-1 "); } screen=1; }
void afisare_matr_adi(void)
{int i,j;
window(1,1,80,25);
textbackground(0);
clrscr();
textcolor(YELLOW);
cprintf("Matricea de adiacenta.");
draw_frame(virf*3+1,virf+2);
textcolor(YELLOW);
for (i=0;i<virf;i++) {
for (j=0;j<virf;j++)
if (matr_adi[i][j]==1) cprintf(" 1 ");
else if (matr_adi[i][j]==0) cprintf(" 0 "); } screen=1; }
void afisare_lista(void)
{ int i;
LISTA *l;
window(1,1,80,25);
textbackground(0);
clrscr();
textcolor(YELLOW);
cprintf("Lista de adiacenta.");
draw_frame(virf*3+7,virf+2);
textcolor(YELLOW);
for (i=0;i<virf;i++) {
l=lista[i];
cprintf(" %02d -",i);
while (l!=NULL) {
cprintf("%3d",l->val);
l=l->next;
}
cprintf("\n\r");
}
screen=1;
}
char afisare_graf(char tip)
{
int i,j,x,y;
radius=RADPERVIRF*virf;
if (radius>MAXRADIUS) radius=MAXRADIUS;
alfa=2*PI/virf;
Graph_Init();
setcolor(WINDCOLTITLE);
outtextxy(10,15,"Afisarea grafica.");
settextjustify(CENTER_TEXT, CENTER_TEXT);
setcolor(WINDCOLBKSEL);
switch (tip) {
case '1': afisare_graf_matr_inc();break;
case '2': afisare_graf_matr_adi();break;
case '3': afisare_graf_lista();break;
}
setfillstyle(1,BLACK);
for (i=0;i<virf;i++) {
getcoord(&x,&y,i);
drawvirf(x,y,i);
}
settextjustify(RIGHT_TEXT, CENTER_TEXT); outtextxy(10,465,"Apasati ori ce tasta."); getch(); closegraph();
screen=1; return 0; }
void afisare_graf_matr_inc(void)
{int i,j,k;
for (i=0;i<arce;i++)
for (j=0;j<virf;j++)
if (tip_inc==0 && matr_inc[i][j]==1) {
for (k=0;k<virf;k++)
if (matr_inc[i][k]==1 && k!=j) joinvirf(j,k,tip_inc);
}
else if (tip_inc==1 && matr_inc[i][j]==-1)
for (k=0;k<virf;k++)
if (matr_inc[i][k]==1) joinvirf(j,k,tip_inc); }
void afisare_graf_matr_adi(void)
{ int i,j;
for (i=0;i<virf;i++)
for (j=0;j<virf;j++)
if (matr_adi[i][j]==1) joinvirf(i,j,tip_adi); }
void afisare_graf_lista(void)
{ LISTA *l;
int i;
for (i=0;i<virf;i++) {
l=lista[i];
while (l!=NULL) {
joinvirf(i,l->val,tip_lista);
l=l->next;
}
}
}
void citire(void)
{
FILE *f;
int i,arce,virf;
char fname[12],str,tip,ch;
wrongname:
clrscr();
cprintf("Citirea grafului:\n\r");
cprintf("Introduceti numele fisierului.\n\r");
cprintf("Nume: ");
scanf("%8s",fname);
for (i=0;i<strlen(fname);i++)
if (!isalnum(fname[i])) {
gotoxy(1,WINDY-1);
cprintf("Nume incorect!");
getch();
goto wrongname;
}
strcat(fname,FEXTENSION);
if ((f=fopen(fname,"r"))==NULL) {
gotoxy(1,WINDY-1);
cprintf("Nu pot sa deschid fisierul de intrare.");
getch();
return;
}
fscanf(f,"%c:%c %d,%d",&str,&tip,&arce,&virf);
if (arce>MAXARC || virf>MAXVIRF || arce<MINARC || virf<MINVIRF) {
gotoxy(1,WINDY-1);
cprintf("Numarul arcelor sau virfurilor in afara limitei.");
getch();
return;
}
tip-=48;
switch (str) {
case '1': ch=cit_matr_inc(f,arce,virf,tip);break;
case '2': ch=cit_matr_adi(f,virf,tip);break;
case '3': ch=cit_lista(f,virf,tip);break;
default: {
gotoxy(1,WINDY-1);
cprintf("Fisier de format nedeterminat.");
getch();
return;
}
}
gotoxy(1,WINDY-1);
if (ch==0) cprintf("\nGraful a fost citit cu succes.");
else cprintf("\nGraful nu a fost citit. Erroare.");
getch();
}
char cit_matr_inc(FILE *f, int arc_new, int virf_new, char tip)
{int i,j,k,val;
char ch,cp,cm;
freematr(matr_adi,virf);matr_adi=NULL;
freelista(lista,virf);lista=NULL;
freematr(matr_inc,arce);
arce=arc_new;
virf=virf_new;
tip_inc=tip;
clrscr();
cprintf("Citirea matricei de incedenta.");
cprintf("\n\rNumarul arcelor: %d",arce);
cprintf("\n\rNumarul virfurilor: %d",virf);
cprintf("\n\rOrientarea grafului: %s",tip_inc?"ORIENTAT\0":"NEORIENTAT\0");
getch();
matr_inc=getmatr(arce,virf);
tip_lista=tip_adi=-1;
for (i=0;i<arce;i++) {
cp=0;cm=0;
for (j=0;j<virf;j++) {
fscanf(f,"%d",&val);
cprintf("\n\rU[%d],X[%d]: %d",i,j,val);
if (val==-1) cm++;
else if (val==1) cp++;
if (val!=0 && val!=1 && val!=-1) {
cprintf(" - ERROARE");
tip_inc=-1;
return -1;
}
matr_inc[i][j]=val;
}
if (tip_inc==0) {
if (cp!=2) {
cprintf("\n\rLinia %d contine erroare.",i);
tip_inc=-1;
return -1;
}
}
else if (cp>1 || (cm>1 && tip_inc==1)) {
cprintf("\n\rLinia %d contine erroare.",i);
tip_inc=-1;
return -1;
}
}
for (i=0;i<arce-1;i++)
for (j=i+1;j<arce;j++)
for (k=0;k<virf;k++)
if (matr_inc[i][k]==matr_inc[j][k]) {
if (k==virf-1) {
cprintf("\n\rMatricea contine arce ce se repeta.");
tip_inc=-1;
return -1;
}
}
else break;
return 0;
}
char cit_matr_adi(FILE *f, int virf_new, char tip)
{ int i,j,val;
char ch;
freematr(matr_inc,arce);matr_inc=NULL;
freelista(lista,virf);lista=NULL;
freematr(matr_adi,virf);
virf=virf_new;
tip_adi=tip;
clrscr();
cprintf("Citirea matricei de adiacenta.");
cprintf("\n\rNumarul virfurilor: %d",virf);
cprintf("\n\rOrientarea grafului: %s",tip_adi?"ORIENTAT\0":"NEORIENTAT\0");
getch();
matr_adi=getmatr(virf,virf);
tip_lista=tip_inc=-1;
for (i=0;i<virf;i++) {
for (j=0;j<virf;j++) {
fscanf(f,"%d",&val);
cprintf("\n\rX[%d][%d]: %d",i,j,val);
if (val!=0 && val!=1) {
cprintf(" - ERROARE");
tip_adi=-1;
return -1;
}
matr_adi[i][j]=val;
}
}
if (tip_adi==0)
for (i=0;i<virf-1;i++)
for (j=i;j<virf-1;j++)
if (matr_adi[j+1][i]!=matr_adi[i][j+1]) {
cprintf("\n\rLinia sau coloana %d contine erroare.",i);
tip_adi=-1;
return -1;
}
return 0;
}
char cit_lista(FILE *f, int virf_new, char tip)
{
int i,j,val;
char ch;
LISTA *l,*lc;
freematr(matr_inc,arce);matr_inc=NULL;
freematr(matr_adi,virf);matr_adi=NULL;
freelista(lista,virf);
virf=virf_new;
tip_lista=tip;
clrscr();
cprintf("Citirea listei de adiacenta.");
cprintf("\n\rNumarul virfurilor: %d",virf);
cprintf("\n\rOrientarea grafului: %s",tip_lista?"ORIENTAT\0":"NEORIENTAT\0");
getch();
lista=getlista(virf);
tip_inc=tip_adi=-1;
for (i=0;i<virf;i++) {
j=0;
do {
fscanf(f,"%d",&val);
cprintf("\n\rX[%d][%d]: %d",i,j,val);
lc=lista[i];
while (lc!=NULL) {
if (lc->val==val) {
cprintf(" - ERROARE");
tip_lista=-1;
return -1;
}
lc=lc->next;
}
if (val<0) {
cprintf(" - ERROARE");
tip_lista=-1;
return -1;
}
else if (val<virf) {
if (j++==0) lista[i]=l=getlista_el();
else {
l->next=getlista_el();
l=l->next;
}
l->val=val;
}
} while (val<virf && j<virf);
}
return 0;
}
void salvare(void)
{
FILE *f;
int i;
char fname[12],str,tip;
if (control_graf()==1) return;
wrongchoose:
str=show_menu(MENU_SAVE);
if (str=='0') return;
switch (str) {
case '1': tip=tip_inc;break;
case '2': tip=tip_adi;break;
case '3': tip=tip_lista;break;
}
if (tip==-1) {
cprintf("Nu este introdusa.");
getch();
goto wrongchoose;
}
tip+=48;
wrongname:
clrscr();
cprintf("Salvarea grafului:\n\r");
cprintf("Introduceti numele fisierului.\n\r");
cprintf("Nume: ");
scanf("%8s",fname);
for (i=0;i<strlen(fname);i++)
if (!isalnum(fname[i])) {
gotoxy(1,WINDY-1);
cprintf("Nume incorect!");
getch();
goto wrongname;
}
strcat(fname,FEXTENSION);
if ((f=fopen(fname,"w"))==NULL) {
gotoxy(1,WINDY-1);
cprintf("Nu pot sa creez fisierul de iesire.");
getch();
return;
}
fprintf(f,"%c:%c %d,%d\n",str,tip,arce,virf);
switch (str) {
case '1': sal_matr_inc(f);break;
case '2': sal_matr_adi(f);break;
case '3': sal_lista(f);break;
}
fclose(f);
gotoxy(1,WINDY-1);
cprintf("Graful este salvat: %s",fname);
getch();
}
void sal_matr_inc(FILE *f)
{
int i,j;
for (i=0;i<arce;i++) {
for (j=0;j<virf;j++) fprintf(f," %2d",matr_inc[i][j]);
fprintf(f,"\n");
}
}
void sal_matr_adi(FILE *f)
{
int i,j;
for (i=0;i<virf;i++) {
for (j=0;j<virf;j++) fprintf(f," %2d",matr_adi[i][j]);
fprintf(f,"\n");
}
}
void sal_lista(FILE *f)
{
int i;
LISTA *l;
for (i=0;i<virf;i++) {
l=lista[i];
while (l!=NULL) {
fprintf(f," %2d",l->val);
l=l->next;
}
fprintf(f," %2d\n",virf);
}
}
void iesire(void)
{switch (show_menu(MENU_EXIT)) {
case '1': exit(0);
case '0': break;
}
}
void transformare(void)
{
char tip1,tip2;
if (control_graf()==1) return;
do {
switch (tip1=show_menu(MENU_TRANS1)) {
case '1': if (tip_inc==-1) tip1=-1;break;
case '2': if (tip_adi==-1) tip1=-1;break;
case '3': if (tip_lista==-1) tip1=-1;break;
case '0': return;
}
if (tip1==-1) {
cprintf("Nu este introdusa.");
getch();
}
} while (tip1==-1);
do {
switch (tip2=show_menu(MENU_TRANS2)) {
case '1': if (tip1==tip2) tip2=-1;break;
case '2': if (tip1==tip2) tip2=-1;break;
case '3': if (tip1==tip2) tip2=-1;break;
case '0': return;
}
if (tip2==-1) {
cprintf("Selectati tip diferit.");
getch();
}
} while (tip2==-1);
tip1-=49;
tip2-=49;tip2*=3;
tip1+=tip2;
switch (tip1) {
case 1: trans_adi_inc();break;
case 2: trans_lista_inc();break;
case 3: trans_inc_adi();break;
case 5: trans_lista_adi();break;
case 6: trans_inc_lista();break;
case 7: trans_adi_lista();break;
}
cprintf("Transformarea s-a petrecut cu succes.");
getch();
}
void trans_adi_inc(void)
{
int i,j,k=0;
for (i=0;i<virf;i++)
for (j=0;j<virf;j++) if (matr_adi[i][j]==1 && i!=j) k++;
freematr(matr_inc,arce);
arce=k;
matr_inc=getmatr(arce,virf);
for (i=0;i<arce;i++)
for (j=0;j<virf;j++) matr_inc[i][j]=0;
k=0;
if (tip_adi==1) {
for (i=0;i<virf;i++)
for (j=0;j<virf;j++)
if (matr_adi[i][j]==1 && i!=j) {
matr_inc[k][i]=-1;
matr_inc[k++][j]=1;
}
}
else {
arce/=2;
for (i=0;i<virf-1;i++)
for (j=i+1;j<virf;j++)
if (matr_adi[i][j]==1 && i!=j) {
matr_inc[k][i]=1;
matr_inc[k++][j]=1;
}
}
tip_inc=tip_adi;
}
void trans_inc_adi(void)
{
int i,j,k;
freematr(matr_adi,virf);
matr_adi=getmatr(virf,virf);
for (i=0;i<virf;i++)
for (j=0;j<virf;j++) matr_adi[i][j]=0;
for (j=0;j<virf;j++)
for (i=0;i<virf;i++)
if ((tip_inc==1 && matr_inc[i][j]==-1) || (tip_inc==0 && matr_inc[i][j]==1)) {
for (k=0;k<virf;k++)
if (matr_inc[i][k]==1 && k!=j) {
matr_adi[j][k]=1;
break;
}
}
tip_adi=tip_inc;
}
void trans_inc_lista(void)
{int i,j,k,m;
LISTA *l;
freelista(lista,virf);
lista=getlista(virf);
for (j=0;j<virf;j++) {
m=0;
for (i=0;i<virf;i++)
if ((tip_inc==1 && matr_inc[i][j]==-1) || (tip_inc==0 && matr_inc[i][j]==1))
for (k=0;k<virf;k++)
if (matr_inc[i][k]==1 && k!=j) {
if (m++==0) lista[j]=l=getlista_el();
else {
l->next=getlista_el();
l=l->next;
}
l->val=k;
break;
}
}
tip_lista=tip_inc;
}
void trans_lista_inc(void)
{int i,j,k;
LISTA *l;
freematr(matr_inc,arce);
k=0;
for (i=0;i<virf;i++) {
l=lista[i];
while (l!=NULL) {
k++;
l=l->next;
}
}
//if (tip_lista==0) arce=k/2;
arce=k; // ?????????????????????????//
matr_inc=getmatr(arce,virf);
for (i=0;i<arce;i++)
for (j=0;j<virf;j++) matr_inc[i][j]=0;
k=0;
for (i=0;i<virf;i++) {
l=lista[i];
while (l!=NULL) {
if (tip_lista==1) matr_inc[k][i]=-1;
else matr_inc[k][i]=1;
matr_inc[k][l->val]=1;
k++;
l=l->next;
}
}
tip_inc=tip_lista;
}
void trans_adi_lista(void)
{int i,j,m;
LISTA *l;
freelista(lista,virf);
lista=getlista(virf);
for (i=0;i<virf;i++) {
m=0;
for (j=0;j<virf;j++)
if (matr_adi[i][j]==1) {
if (m++==0) lista[i]=l=getlista_el();
else {
l->next=getlista_el();
l=l->next;
}
l->val=j;
}
}
tip_lista=tip_adi;
}
void trans_lista_adi(void)
{int i,j;
LISTA *l;
freematr(matr_adi,virf);
matr_adi=getmatr(virf,virf);
for (i=0;i<virf;i++)
for (j=0;j<virf;j++) matr_adi[i][j]=0;
for (i=0;i<virf;i++) {
l=lista[i];
while (l!=NULL) {
matr_adi[i][l->val]=1;
l=l->next;
}
}
tip_adi=tip_lista;
}
void prelucrare(void) {if (control_graf()==1) return;}
char control_graf(void) {
if (tip_inc==-1 && tip_adi==-1 && tip_lista==-1) { // window(1,1,80,25);
draw_frame(26,3);
textcolor(WINDCOLBKSEL);
cprintf("Nu este posibil.\n\r");
cprintf("Graful nu este introdus.");
screen=1;
getch();
return 1;
}
return 0;
}
void read_matr_adi(void)
{
int i,j;
char ch;
freematr(matr_inc,arce);matr_inc=NULL;
freelista(lista,virf);lista=NULL;
freematr(matr_adi,virf);
clrscr();
cprintf("Introduceti numarul virfurilor: ");
do scanf("%d",&virf); while (virf<MINVIRF || virf>MAXVIRF);
cprintf("\rGraful este orientat ? (D/N): ");
do {
ch=toupper(getch());
if (ch=='D') tip_adi=1;
else if (ch=='N') tip_adi=0;
} while (ch!='D' && ch!='N');
cprintf("%c",ch);
cprintf("\n\rIntroduceti matricea:");
matr_adi=getmatr(virf,virf);
tip_lista=tip_inc=-1;
for (i=0;i<virf;i++) {
for (j=0;j<virf;j++) {
cprintf("\n\rX[%d][%d]: ",i,j);
do {
ch=getch();
if (ch=='1') matr_adi[i][j]=1;
else if (ch=='0') matr_adi[i][j]=0;
} while (ch!='1' && ch!='0');
cprintf("%c",ch);
}
}
if (tip_adi==0)
for (i=0;i<virf-1;i++)
for (j=i;j<virf-1;j++)
if (matr_adi[j+1][i]!=matr_adi[i][j+1]) {
cprintf("\n\rLinia sau coloana %d contine erroare.",i);
tip_adi=-1;
getch();
}
/*else for (i=1;i<virf;i++)
for (j=0;j<i;j++)
if (matr_adi[i][j]!=0) {
printf("\n\rLinia sau coloana %d contine erroare.",i);
tip_adi=-1;
}*/
}
void read_matr_inc(void)
{int i,j,k;
char ch,cp,cm;
freematr(matr_adi,virf);matr_adi=NULL;
freelista(lista,virf);lista=NULL;
freematr(matr_inc,arce);
clrscr();
cprintf("Introduceti numarul virfurilor: ");
do scanf("%d",&virf); while (virf<MINVIRF || virf>MAXVIRF);
cprintf("\rIntroduceti numarul arcelor: ");
do scanf("%d",&arce); while (arce<MINARC || arce>MAXARC);
cprintf("\rGraful este orientat ? (D/N): ");
do {
ch=toupper(getch());
if (ch=='D') tip_inc=1;
else if (ch=='N') tip_inc=0;
} while (ch!='D' && ch!='N');
cprintf("%c",ch);
cprintf("\n\rIntroduceti matricea:");
matr_inc=getmatr(arce,virf);
tip_lista=tip_adi=-1;
for (i=0;i<arce;i++) {
lineerror:
cp=0;cm=0;
for (j=0;j<virf;j++) {
cprintf("\n\rX[%d][%d]: ",i,j);
do {
ch=getch();
if (ch=='1') {matr_inc[i][j]=1;cp++;}
else if (ch=='0') matr_inc[i][j]=0;
else if (ch=='-' && tip_inc==1) {matr_inc[i][j]=-1;cm++;}
} while (ch!='1' && ch!='0' || (ch=='-' && tip_inc==0));
if (isdigit(ch)) cprintf("%c",ch);
else cprintf("-1");
}
if (tip_inc==0) {
if (cp!=2) {
cprintf("\n\rLinia %d contine erroare.\n\rIntroduceti-o din nou.",i);
goto lineerror;
}
}
else if (cp>1 || (cm>1 && tip_inc==1)) {
cprintf("\n\rLinia %d contine erroare.\n\rIntroduceti-o din nou.",i);
goto lineerror;
}
}
for (i=0;i<arce-1;i++)
for (j=i+1;j<arce;j++)
for (k=0;k<virf;k++)
if (matr_inc[i][k]==matr_inc[j][k]) {
if (k==virf-1) {
cprintf("\n\rMatricea contine arce ce se repeta.");
tip_inc=-1;
getch();
return;
}
}
else break;
}
void read_lista(void)
{int i,j,val;
char ch;
LISTA *l,*lc;
freematr(matr_inc,arce);matr_inc=NULL;
freematr(matr_adi,virf);matr_adi=NULL;
freelista(lista,virf);
clrscr();
cprintf("Introduceti numarul virfurilor: ");
do scanf("%d",&virf); while (virf<MINVIRF || virf>MAXVIRF);
cprintf("\rGraful este orientat ? (D/N): ");
do {
ch=toupper(getch());
if (ch=='D') tip_lista=1;
else if (ch=='N') tip_lista=0;
} while (ch!='D' && ch!='N');
cprintf("%c",ch);
cprintf("\n\rIntroduceti lista:\n\r");
lista=getlista(virf);
tip_inc=tip_adi=-1;
for (i=0;i<virf;i++) {
j=0;
do {
cprintf("\rX[%d][%d]: ",i,j);
scanf("%d",&val);
lc=lista[i];
if (val==virf) val++;
while (lc!=NULL) {
if (lc->val==val) {
cprintf("\rVirful a fost introdus deja!");
val=virf;
break;
}
lc=lc->next;
}
if (val<0) cprintf("\rNu exista asa virf!");
else if (val<virf) {
if (j++==0) lista[i]=l=getlista_el();
else {
l->next=getlista_el();
l=l->next;
}
l->val=val;
}
} while (val<=virf && j<virf);
}
/*if (tip_adi==0) {
for (i=0;i<virf-1;i++)
for (j=i;j<virf-1;j++)
if (matr_adi[j+1][i]!=matr_adi[i][j+1]) {
cprintf("\n\rLinia sau coloana %d contine erroare.",i);
tip_adi=-1;
}
}
/*else for (i=1;i<virf;i++)
for (j=0;j<i;j++)
if (matr_adi[i][j]!=0) {
printf("\n\rLinia sau coloana %d contine erroare.",i);
tip_adi=-1;
}*/
}
char **getmatr(int n, int m)
{int i,j;
char **matr;
if ((matr=(char **)calloc(n,sizeof(char *)))==NULL) {
printf("\nNu ajunge memorie pentru pastrarea matricei.");
getch();
exit(1);
}
for (i=0;i<n;i++)
if ((matr[i]=(char *)calloc(m,sizeof(char)))==NULL) {
printf("\nNu ajunge memorie pentru pastrarea matricei.");
getch();
exit(1);
}
return matr;
}
void freematr(char **matr, int n)
{
int i;
if (matr==NULL) return;
for (i=0;i<n;i++) free(matr[i]);
free(matr);
}
LISTA **getlista(int n)
{
LISTA **l;
if ((l=(LISTA **)calloc(n,sizeof(LISTA *)))==NULL) {
printf("\nNu ajunge memorie pentru pastrarea listei.");
getch();
exit(1);
}
return l;
}
LISTA *getlista_el(void)
{LISTA *l;
if ((l=(LISTA *)malloc(sizeof(LISTA)))==NULL) {
printf("\nNu ajunge memorie pentru pastrarea listei.");
getch();
exit(1);
}
l->val=32768;
l->next=NULL;
return l;
}
void freelista(LISTA **l, int n)
{int i;
if (l==NULL) return;
for (i=0;i<n;i++) freelista_el(l[i]);
free(l);
}
void freelista_el(LISTA *l)
{
if (l==NULL) return;
else freelista_el(l->next);
free(l);
}
int show_menu(const char **menu)
{char m=0,m_max=0,m_min=-1,ch=0;
textbackground(WINDCOLBK);
clrscr();
_setcursortype(_NOCURSOR);
for (m=0;menu[m][0]!='\0';m++)
if (isdigit(menu[m][0])) {
textcolor(WINDCOLFR);
cprintf("\n\r%s",menu[m]+1);
if (m_min==-1) m_min=m;
m_max++;
}
else {
textcolor(WINDCOLTITLE);
cprintf("%s",menu[m]+1);
}
m=m_min;
do {
textbackground(WINDCOLBK);
textcolor(WINDCOLFR);
gotoxy(1,m+1);cprintf("%s",menu[m]+1);
switch (ch) {
case 72: if (m>m_min) m--;break;
case 80: if (m<m_max) m++;break;
case 75: m=m_min;break;
case 77: m=m_max;break;
}
textbackground(WINDCOLBKSEL);
textcolor(WINDCOLFRSEL);
gotoxy(1,m+1);cprintf("%s",menu[m]+1);
} while ((ch=getch())!=13);
_setcursortype(_NORMALCURSOR);
textbackground(WINDCOLBK);
textcolor(WINDCOLFR);
gotoxy(1,WINDY-1);
return menu[m][0];
}
void draw_frame(char dx, char dy)
{int i,x1,y1,x2,y2;
window(1,1,80,25);
textbackground(WINDCOLBK);
textcolor(WINDCOLFRAME);
x1=(80-dx)/2;
y1=(25-dy)/2+1;
x2=x1+dx;
y2=y1+dy;
gotoxy(x1,y1);cprintf("г");
for (i=1;i<dx;i++) cprintf("=");
cprintf("¬");
for (i=y1+1;i<y2;i++) {gotoxy(x2,i);cprintf("¦");}
gotoxy(x1,y2);cprintf("L");
for (i=1;i<dx;i++) cprintf("=");
cprintf("-");
gotoxy(x1,y1+1);
for (i=y1+1;i<y2;i++) {gotoxy(x1,i);cprintf("¦");}
window(x1+1,y1+1,x2-1,y2-1);
clrscr();
}
void about(void)
{ //window(1,1,80,25);
draw_frame(60,7); //clrscr();
textcolor(WINDCOLFR);
cprintf("Universitate Tehnica a Moldovei\n\r");
cprintf("Facultatea Calculatoare, Informatica, Microelectronica\n\r");
cprintf("Disciplina: Matematica Discreta\n\r");
cprintf("Lucrare de laborator Nr. 1\n\r");
cprintf("Tema: Pastrarea grafurilor in memoria calculatorului\n\r");
cprintf("A efectuat: Lazari Alexei, studentul grupei TI-001");
screen=1;
getch();
}
void Graph_Init(void)
{int graphdriver=DETECT, graphmode, errorcode;
errorcode=graphresult();
if (errorcode < 0) {
printf("\n\rGraphics System Error: %s\n",grapherrormsg(errorcode));
exit(9);
}
initgraph(&graphdriver, &graphmode, "");
errorcode=graphresult();
if (errorcode != grOk) {
printf("\n\rGraphics System Error: %s\n",grapherrormsg(errorcode));
exit(9);
}
}
void getcoord(int *x, int *y, int v)
{*x=ORIGX+radius*cos(alfa*v); *y=ORIGY-radius*sin(alfa*v); }
void drawvirf(int x, int y, int v)
{char num[3]; itoa(v+1,num,10); fillellipse(x,y,VIRFRADIUS,VIRFRADIUS);
setcolor(WINDCOLFRAME); circle(x,y,VIRFRADIUS); circle(x,y,VIRFRADIUS+1); setcolor(WINDCOLFR);
outtextxy(x,y,num); }
void joinvirf(int v1, int v2, char tip)
{int x1,y1,x2,y2; getcoord(&x1,&y1,v1); getcoord(&x2,&y2,v2); line(x1,y1,x2,y2); tip++; }
setbkcolor – functia data are prototipul in biblioteca graphics.h . Cu ajutorul ei se poate seta culoarea background-ului.
setcolor - functia data are prototipul in biblioteca graphics.h . Cu ajutorul ei se seteaza culoarea textului la afisare.
outtextxy – functia data are prototipul in biblioteca graphics.h . Cu ajutorul ei se poate aduce un text. Functia mai are ca
parametri coordonatele x,y unde si se afiseaza textul.
delay - functia data are prototipul in biblioteca dos.h . Ia are menirea de a face o pauza. Durata se indica in milisecunde.
putpixel - functia data are prototipul in biblioteca graphics.h . Pune un pixel cu coordonatele ce se indica.
closegraph - functia data are prototipul in biblioteca graphics.h . Functia de inchidere a regimului grafic.
strcat – concatineaza doua siruri de caractere.
remove – functia de stergere a unui fisier.
6. Variante pentru lucrul individual. Sarcini:
1.Program care citeste din fisier 3 propozitii si le afiseaza in ordinea inversa, apoi le salvează în alt fişier.
2.Sa se scrie un program care creaza un fisier numbers.txt pe discul D, in care inscrie 5 numere intregi, introduse
de la tastatura. Fiecare se scrie pe linie separata, apoi se afişează la ecran.
3. Intr-un fisier "cod.dat" este memorata o tabela de codificare, sub forma: car_de_codif ' ' car_codif '\n'. Sa
se preia un text din fisierul "dat1.dat", sa se codifice conform codului, iar textul obtinut sa se scrie in fisierul
"dat2.txt".
4.Sa se calculeze cat timp a trecut de la inceputul erei noastre.Structurile de baza sunt:
deceniu={veac,era}
timp={ora,minutul,secunda}
data={zi,luna,an}; apoi le salvează în alt fişier
5. Sa se scrie un program care creaza un fisier cu 10 elemente de tip intreg. Citeste din fisier si calculeaza
suma acestor elemente, apoi se afişează la ecran şi le salvează în alt fişier.
6. Sa se interclaseze continutul a doua fisiere intr-un al treilea fisier. Informatiile dintr-un fisier sunt:
numarul_de_valori '\n' val1 '\n' val2 '\n'... Valorile intregi val1, val2, etc. sunt strict crescatoare. Valorile comune
se trec o singura data in fisierul rezultant.
7. Dintr-un fisier se citesc 15 caractere distincte, care codifica cifrele zecimale 0,1,2...9 si operatorii +,-,*,/ si
=. Tot din fisier se citeste un sir de maxim 80 de caractere, terminat prin caracterul '='si care reprezinta o expresie
aritmetica cu operanzi intregi fara semn. Se considera expresie corecta cea care satisface urmatoarele conditii:
- contine numai caractere ale carei coduri au fost citite initial
- nu contine doi operatori succesivi
- nu contine impartiri la zero.
Daca expresia este incorecta se afiseaza un mesaj de eroare corespunzator primei erori intilnite. Daca expresia
este corecta se va evalua, efectuind operatiile de la stinga la dreapta in ordinea in care apar si se va afisa valoarea
calculata codificata conform listei de coduri date.
8. Dintr-un fisier de intrare se citeste o propozitie terminata printr-un punct. Propozitia este formata din
cuvinte ce contin doar litere mari. Cuvintele sunt separate prin unul sau mai multi separatori din multimea
blanc,'\t','\n'. Stiind ca propozitia are cel mult 30 de cuvinte, sa se afiseze grupurile de cuvinte in care fiecare
membru reprezinta anagrama altui membru din grup. Un grup va contine numarul maxim de membrii, iar
membrii sunt distincti.
9.Un fisier contine 7 linii, pe fiecare scriind o zi a saptamanii urmata dupa un spatiu de suma cheltuita in ziua
respectiva, apoi se afişează la ecran.
10. Sa se scrie un program C ce prelucreaza fisierul de mai sus (9) si afiseaza suma totala cheltuita, ziua cu
suma maxima si suma medie. Daca sunt mai multe zile cu aceeasi suma maxima, puteti tipari doar prima zi in
care s-a cheltuit suma sau toate.
11) Se cere programul C care sa afiseze dimensiunea in octeti a fisierului de tip text AUTOEXEC.BAT aflat pe
discul D: .
12) Scrieti un program care sa citeasca de la tastatura numele a n studenti pe care sa le memoreze intr-un fisier cu
numele STUDENTI.TXT de tip text, numele fiind separate intre ele prin <Enter>. Afisati pe ecran ceea ce se scrie
in fisier. Vrificati daca fisierul s-a creat corect folosind comenzi DOS.
13) Pentru fisierul creat anterior sa se scrie programul care il actualizeaza prin adaugarea a inca m studenti la
sfarsitul fisierului. Dupa adaugare se cere generarea unui alt fisier cu numele studentilor in ordine alfabetica.
Folositi functiile qsort si strcmp, precum si pointeri spre siruri de caractere pentru ordonare.
14) Se cere programul pentru a copia continutul unui fisier in alt fisier. Numele celor doua fisiere se vor da in
linia de comanda.
15) Se considera un fisier text anterior creat printr-o metoda oarecare. Scrieti programul care sa determine
numarul de aparitii a fiecarei cifre de la 0 la 9. Pe ecran se va afisa: "Cifra … apare de …ori".
16) Programul urmator trebuie sa realizeze transformarea unui fisier text in alt fisier text, care sa contina doar
litere mari (inlocuirea literelor mici cu litere mari). Numele fisierelor se vor da in linia de comanda. Se cere sa se
completeze programul cu secventele potrivite (inlocuind semnele .. .. cu instructiuni sau functii corespunzatoare).
17) Pentru un concurs de admitere se genereaza un fisier cu numele "concurs.not" care contine numele
candidatilor impreuna cu notele la matematica, la fizica si media. Se cere programul pentru generarea acestui
fisier de la tastatura.
18) Pentru fisierul creat anterior se cere programul de consultare, care sa afiseze pe ecran o inregistrare a unui
candidat identificata prin numarul ei de ordine in fisier.
19) Se cere programul care concateneaza doua fisiere, cu generarea unui al treilea fisier. Numele fisierelor se
preiau din linia de comanda.
20) Se considera un fisier text si doua tablouri de siruri de caractere, care contin cuvinte. Se cere programul C
care pe baza fisierului dat genereaza un alt fisier, inlocuind cuvintele pe care le gaseste in primul tablou cu
cuvintele corespunzatoare din al doilea tablou.
21. Fisierul ELEVI.TXT contine urmatoarele informatii despre elevii unei scoli: numele si prenumele, data
nasterii, clasa, media (numarul de caractere pentru fiecare cimp se deduce din consultarea fisierului).
a). Se cere un tabel pe ecran si intr-un fisier text cu numarul si numele elevilor cu media 10.
22. Sa se creeze un fisier care contine numele tuturor fisierelor text dintr-un director dat ca parametru si din
subdirectoarele acestuia care au cuvinte mai lungi de 15 caractere. Fisierul va fi ordonat alfabetic.
23. Se da un fisier care contine pe fiecare rand un nume (un cuvint) urmat de 5 note. Se cere sa se construiasca un
al doilea fisier care contine numele urmat de medie, ordonat descrescator dupa medie. Daca un nume apare pe
mai multe linii in fisierul original, liniile respective vor fi scrise intr-un fisier cu numele 'eronat', si pentru acestea
nu se va calcula media.
24. Sa se scrie un fisier de comenzi care are ca parametri doua cuvinte si o lista de fisiere. Sa se construiasca un
fisier prin concatenarea fisierelor din lista dupa ce se aplica urmatoarele modificari: pentru fisierele de rang impar
din lista se vor inlocui toate aparitiile primului cuvant cu al doilea, iar pentru fisierele de rang par, se va inlocui
ultima aparitie din fiecare linie a celui de-al doilea cuvant cu primul.
25. Pentru fiecare fisier din linia de comanda se vor afisa toate liniile care sunt mai lungi de 10 caractere. De
asemenea, se vor inlocui toate cifrele cu caracterul 'x'. Liniile unui fisier vor fi precedate de numele fisierului. Se
va face o situatie finala cu numarul liniilor afisate din fiecare fisier, in ordine descrescatoare in functie de numarul
liniilor.
26. Să se scrie în fişier un text în lungime N introdus de la tastatură, apoi afişează la cerere. Operaţiile de I/E în
fişier utilizează funcţiile respective.
27. Să se scrie programul care creează un fişier text în care se memorează două matrice, astfel: pe prima linie numărul
de linii şi numărul de coloane ale primei matrice, separate printr-un spaţiu; pe fiecare din liniile următoare, în ordine,
elementele unei linii din matrice, separate prin cîte un spaţiu; în continuare a doua matrice, în aceeaşi formă.. Apoi de
afişat.
28. Să se scrie programul care înmulţeşte matricele aflate în fişierul creat la problema anterioară. Rezultatul se va
memora în alt fişier, în aceeaşi formă. Dacă înmulţirea nu e posibilă, se va scrie ca rezultat un mesaj de eroare.
Matricele sînt suficient de mici pentru a putea fi încărcate în memorie (n,m =5).
29. Să se scrie programul care numără frecvenţa de apariţie a fiecărei valori dintr-un vector memorat într-un fişier
binar. Rezultatul va fi memorat într-un fişier text astfel: pe fiecare linie, separate printr-un spaţiu, se vor scrie valoarea,
numărul de apariţii şi frecvenţa relativă de apariţie.
30. Matrice memorate în fişiere binare. Pentru lucrul cu matrice memorate în fişiere binare s-a adoptat
următorulmod de organizare: primul articol conţine numărul de linii ale matricei, iar următoarele articole conţin, în
ordine, cîte un element al matricei, în ordine lexicografică. Se va lucra cu matrice cu elemente reale. Numărul de linii
este întreg (primul articol are altă dimensiune). Să se scrie programul care memorează într-un fişier binar o matrice
introdusă de la tastatură.
31. Se dă un fișier care conține un şir alfanumeric(80). De determinat elementele şirului care corespund
respectivului sistem numeric (zecimal, octal, hexazecimal sau binar) şi de grupat pe categorii, aflîndu-le valorile în
sistemul zecimal, totodată, aranjîndu-le în creştere.
32. Într-un fișier este dat un şir S de numere întregi. Elementele şirului fiind alcătuite aleatoriu din mai multe cifre
de 1,2 şi 3, formînd subşiruri de trei cifre, şi orice două elemente ale subşirului pot fi iinterschimbate. Se cere de
efectuat minimul de iinterschimbări , astfel încît din şirul dat S să obţineţi altfel de subşiruri în care pe primele K
poziţii se află unităţi, urmatoarele L poziţii conţin numărul 2, iar restul sunt pozitii cu numarul 3. Argumentaţi motivul
metodei alese din punct de vedere de eficienţă.
33. Sa se caute in directorul specificat toate programele sursa de tip *.CPP si sa se salveze în alt fișier și să se
afiseze pe ecran, caracter cu caracter, aceste programe determinadu-se si afisandu-se pentru fiecare numarul de
linii sursa.
34. Sa se creeze, in directorul curent, mai multe fisiere text, caracter cu caracter, precizandu-se pentru fiecare,
prin dialog, numele si extensia.
35. Sa se includa, printr-o functie adecvata de includere include(), intr-un fisier text, dupa o linie al carei
numar de secventa este precizat, un alt fisier text anterior creat.
Bibliografie:
1. ."Limbajul de programare C". Brian W.Kernighan. Dennis M.Ritchie.
2. Liviu Negrescu. ”Limbajul de programare C şi C++” V.1-4. Buc. 1999
3. Bacivarov, A.; Nastac, I. - "Limbajul C. Indrumar de laborator", Tipografia UPB, Bucuresti, 1997.
4. BibliogrШилдт, Герберт. Полный справочник по С, 4-е издание. : Пер. с англ. - М,: Издательский дом "Вильямс",
2002. - 704 с. : ил. - Парал.т ит. англ.
5. Павловская Т.А. С/C++. Программирование на языке высокого уровня. / Т.А. Павловская. - СПб.: Питер, 2002. -
464 с.: ил.
6. Культин Н.Б. C/C++ в задачах и примерах. - СПб.:БХВ-Петербург, 2001. - 288 с.: ил.
7. Першиков В.И., Савинков В.М. Толковый словарь по информатике.-М.: Финансы и статистика, 1991. - 543 с.