next up previous contents
Next: Comentarea programului Up: Problema rezolvata Previous: Problema rezolvata   Cuprins


Codul sursa

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



Cristian Gavrila 2001-10-02