#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();
}