#include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <ctype.h> #define Max 100 /* lungimea maxima a unei linii */ /* tipul pentru nodul listei */ typedef struct elem { char *id; int valoare; struct elem *urm; } nod; nod *radacina=NULL; /* pastreaza inceputul listei */ /*---------------------------------------------------------*/ /* */ /* Functia caut cauta sirul s in lista al carei inceput */ /* e indicat de parametrul lista. Daca sirul apare in lista*/ /* atunci functia returneaza pointerul la nodul respectiv, */ /* in caz contrar returneaza NULL */ /* */ /*---------------------------------------------------------*/ nod *caut(nod *lista, char *s) { nod *q1; for (q1=lista; q1!=NULL && strcmp(q1->id, s)<0; q1=q1->urm); /* caut 1 */ if (q1!=NULL && strcmp(q1->id, s)==0) /* caut 2 */ return q1; /* daca sirul s a fost gasit in lista */ return NULL; } /*---------------------------------------------------------*/ /* */ /* Functia listez parcurge lista si pentru fiecare nod */ /*afiseaza identificatorul memorat si valoarea atasata lui.*/ /*Deoarece lista este ordonata, afisarea identificatorilor*/ /* este in ordine alfabetica */ /* */ /*---------------------------------------------------------*/ void listez(void) { nod *q; for (q=radacina; q!=NULL; q=q->urm) printf("Identificator: %s Valoare: %d\n",q->id,q->valoare); } /*---------------------------------------------------------*/ /* Functia sterg elimina din lista indicata de pointerul */ /* lista, nodul ce are campul id egal cu argumentul s */ /* */ /*---------------------------------------------------------*/ nod *sterg(nod *lista, char *s) { nod *q1, *q2; for (q1=q2=lista; q1!=NULL && strcmp(q1->id, s)<0; q2=q1,q1=q1->urm); /* sterg 1 */ /* se parcurge lista cautandu-se nodul avand */ /* campul id egal cu sirul s */ if (q1!=NULL && strcmp(q1->id, s)==0) /* sterg 2 */ { /* daca s-a gasit un astfel de nod */ if (q1!=q2) /* daca nodul nu este la inceputul listei */ /* sterg 3 */ q2->urm = q1->urm; /* elimina nodul din lista */ else /* nodul apare la inceputul listei */ lista = lista->urm; /* sterg 4 */ free(q1->id); /* se elibereaza memoria ocupata de nodul eliminat */ free(q1); return lista; /*returneaza pointerul catre inceputul listei modificate*/ } else { printf("Eroare: identificatorul %s nu apare in lista\n", s); return lista; } } /*---------------------------------------------------------*/ /* */ /* Functia introduc insereaza un nod in lista ordonata, */ /* indicata de parametrul lista. Lista ramine ordonata si */ /* dupa inserare. Nodul nou are campul id egal cu sirul */ /* indicat de parametrul s, iar campul valoare egal cu */ /* parametrul v. Functia returneaza pointerul catre */ /* inceputul listei modificate */ /* */ /*---------------------------------------------------------*/ nod *introduc(nod *lista, char *s, int v) { nod *q1, *q2, *aux; if ((aux=(nod *)malloc(sizeof(nod)))==NULL || (aux->id=(char *)malloc(strlen(s)+1))==NULL) /* introduc 1 */ { /* daca nu e memorie suficienta pentru a crea un nod nou, respectiv pentru a memora sirul s, se da un mesaj de eroare dupa care executia e incheiata */ printf("Eroare: memorie insuficienta\n"); exit(1); } strcpy(aux->id, s); /* se salveaza s in nodul nou */ aux->valoare=v; /* se salveaza v in nodul nou */ /* nodul nou este inserat in lista ordonata astfel incat ea ramane ordonata si dupa inserare. Lista este parcursa cautandu-se primul nod avand campul id mai mare sau egal cu s */ for (q2=q1=lista; q1!=NULL && strcmp(q1->id, s)<0; q2=q1, q1=q1->urm); /* introduc 2 */ if (q1!=NULL && strcmp(q1->id, s)==0) /* introduc 3 */ /* daca in lista apare un nod avand campul id egal cu s, atunci se afiseaza un mesaj de eroare si se pastreaza lista nemodificata*/ { printf("Eroare: %s apare in tabela\n", s); return lista; } if (q1!=q2) /* daca inserarea nu se face la inceputul listei*/ /* introduc 4 */ { q2->urm=aux; aux->urm=q1; return lista ; } /* daca inserarea se face la inceputul listei */ /* introduc 5 */ aux->urm=lista; return aux; } /*-------------------------------------------------------------*/ /* */ /*Functia citesc_linie citeste urmatoarea linie de la tastatura */ /*si recunoaste identificatorul si valoarea asociata lui. */ /*Identificatorul este returnat in parametrul s, */ /*iar valoarea in parametrul val */ /* */ /*-------------------------------------------------------------*/ void citesc_linie(char *s, int *val) { int i, j; char temp[Max]; /* citeste urmatoarea linie de la tastatura */ gets(temp); /* citesc_linie 1 */ s[0]='\0'; /* initializeaza valorile argumentelor */ for (i=0; temp[i]!='\0'; ) /* atata timp cat nu a fost atins sfarsitul sirului */ /* citesc_linie 2 */ { if (isalpha(temp[i])) /* daca incepe un identificator */ /* citesc_linie 3 */ { j=0; /* memoreaza identificatorul in s */ while (isalnum(temp[i])) s[j++]=temp[i++]; /* citesc_linie 4 */ /* memoreaza sfarsitul de sir */ s[j]='\0'; /* citesc_linie 5 */ continue; } if (isdigit(temp[i])) /* daca incepe un numar */ /* citesc_linie 6 */ { *val=0; while (isdigit(temp[i])) /* citesc_linie 7 */ { /* calculeaza valoarea numarului */ *val=*val*10+temp[i]-'0' ; /* citesc_linie 8 */ i++; } continue; } /* altfel se trece peste caracterul curent */ i++; /* citesc_linie 9 */ } /* while */ } /*----------------------------------------------------------*/ /* */ /* Functia comanda_a realizeaza functionalitatea comenzii a */ /* */ /*----------------------------------------------------------*/ void comanda_a(void) { int val; char s[Max]; citesc_linie(s, &val); /* citeste o linie de la tastatura */ if (strlen(s)!=0) /* daca linia e corecta */ radacina=introduc(radacina, s, val); else printf("Eroare : linie incorecta\n"); } /*---------------------------------------------------------*/ /* */ /* Functia comanda_t realizeaza functionalitatea comenzii t */ /* */ /*---------------------------------------------------------*/ void comanda_t(void) { int val; char s[Max]; nod *p; citesc_linie(s, &val); /* citeste o linie de la tastatura */ if (strlen(s)==0) /* daca linia e incorecta */ {printf("Eroare: linie incorecta\n"); return;} if ((p=caut(radacina, s))!=NULL) /* cauta nodul in lista */ printf("Identificator:%s Valoare:%d\n", p->id, p->valoare); else printf("Eroare: Identificator nedefinit\n"); } /*---------------------------------------------------------*/ /* */ /* Functia comanda_s realizeaza comanda s */ /* */ /*---------------------------------------------------------*/ void comanda_s(void) { char s[Max]; int val; citesc_linie(s, &val); /* citeste o linie de la tastatura */ if (strlen(s)==0) /* daca linia citita e incorecta */ {printf("Eroare: linie incorecta\n"); return;} radacina=sterg(radacina, s); /* sterge nodul din lista */ } /*---------------------------------------------------------*/ /* */ /* Functia comanda_oper executa operatiile legate de */ /* comenzile +, -, *, / */ /* Se citesc cei doi operatori si se executa operatia */ /* dorita. Rezultatul este afisat. */ /* */ /*---------------------------------------------------------*/ void comanda_oper(char c) { char s1[Max], s2[Max]; int val; nod *p1, *p2; /* se citeste primul operand */ citesc_linie(s1, &val); /* comanda_oper 1 */ /* se citeste al doilea operand */ citesc_linie(s2, &val); /* comanda_oper 2 */ if (strlen(s1)!=0 && strlen(s2)!=0) if(((p1=caut(radacina, s1))!=NULL) && ((p2=caut(radacina, s2))!=NULL)) /* comanda_oper 3 */ /* se verifica daca operanzii apar in lista */ { switch(c) /* functie de tipul comenzii */ { case '+': val=p1->valoare+p2->valoare; break; case '-': val=p1->valoare-p2->valoare; break; case '*': val=p1->valoare*p2->valoare; break; case '/': if (p2->valoare!=0) val=p1->valoare/p2->valoare; else printf("Eroare: Impartire la 0\n"); break; } printf("Rezultatul operatiei e %d\n", val); } else printf("Operand nedefinit\n"); else printf("Eroare: linie eronata\n"); } /*-----------------------------------------------------------*/ /* */ /* Functia meniu afiseaza meniul programului,citeste comanda */ /* si apeleaza subrutina corespunzatoare */ /* */ /*-----------------------------------------------------------*/ void meniu(void) { char o; while(1) /* meniu 1 */ { clrscr(); /* se afiseaza meniul programului */ puts("a : adauga un identificator si valoarea asociata"); puts("t : tipareste valoarea asociata unui identificator"); puts("s : sterge un identificator"); puts("l : listeaza identificatorii si valorile asociate"); puts("+ : calculeaza suma pentru 2 identificatori"); puts("- : calculeaza diferenta pentru 2 identificatori"); puts("* : calculeaza produsul pentru 2 identificatori"); puts("/ : calculeaza impartirea pentru 2 identificatori"); puts("f : termina programul"); printf("\nOptiunea: "); o=getche(); /* meniu 2 */ printf("\n\n"); switch (tolower(o)) /* meniu 3 */ { case 'a': comanda_a(); break; case 't': comanda_t(); break; case 's': comanda_s(); break; case 'l': listez(); break; case '+': case '-': case '*': case '/': comanda_oper(o); break; case 'f': return; default: printf("Eroare : Comanda inexistenta\n"); } printf("\nApasa orice tasta..."); getch(); } } /*----------------------------------------------------*/ /* */ /* Functia main apeleaza functia meniu */ /* */ /*----------------------------------------------------*/ void main(void) { meniu(); }