#include "stdio.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"


struct eintrag_
{
char *name;
char *nr;
struct eintrag_ * before;
struct eintrag_ * next;
};

typedef struct eintrag_ * eintrag;

void* alloc(int);

eintrag create_entry(char*, char*);
int add_list(eintrag);
int del_list(char*);
eintrag search_list(char*);
int alph_cmp(eintrag,eintrag);
void print_list();
void print_entry(eintrag);

eintrag start=NULL;

int main()
{
eintrag a;
char c[30],d[30];
int b;

printf("Alphabetische Telefonnummerverwaltung");

while(1)
{

printf("\n\n(1) Eintrag hinzufügen\n(2) Eintrag löschen\n
(3) Eintrag suchen\n(4) Einträge auflisten\n(5) Ende\n\n");
scanf("%d",&b);
if(b==1)
{
	printf("\nBitte Name eingeben: ");
	scanf("%s",c);
	printf("Bitte Tel-Nr eingeben: ");
	scanf("%s",d);
	a=create_entry(c,d);
	if(!add_list(a))printf("\n\nName bereits vorhanden");
}
if(b==2)
{
	printf("\nBitte zu löschenden Namen eingeben: ");
	scanf("%s",c);
	if(!del_list(c))printf("\n\nName konnte nicht gefunden werden!");
}
if(b==3)
{
	printf("\nBitte zu suchenden Namen eingeben: ");
	scanf("%s",c);
	a=search_list(c);
	if(a!=NULL)print_entry(a);
	else printf("\n\nName konnte nicht gefunden werden!");
}
if(b==4)
{
print_list();
}
if(b==5)
{
exit(1);
}
}

}

eintrag create_entry(char* name, char* nr)
{
eintrag neu;

neu = (eintrag)malloc(sizeof(struct eintrag_));  //speicher für eintrag
																 //holen
strupr(name);     //großschreibung
strupr(nr);

neu->name=strdup(name);   //speicher für string holen
neu->nr=strdup(nr);

neu->next=NULL;       //zeiger auf nächstes und vorheriges element auf null
neu->before=NULL;


return neu;

}

int add_list(eintrag  element)
{
if(search_list(element->name)==NULL)    //name schon vorhanden?
{
if(start==NULL || alph_cmp(start,element))   //erstes element oder
{                                            //alph. kleiner?
element->next=start;     //start eins nach hinten schieben
if(start!=NULL)start->before=element;
start=element;          //startzeiger aufs neue element setzen
}
else
{
eintrag p=start;
while(p->next!=NULL && !alph_cmp(p->next,element)) //so lange in der sort. liste
{                    //weiter, bis folg. eintrag alph. größer
p=p->next;
}
element->next=p->next;     //element dazwischen reinschieben
element->before=p;
p->next=element;
}

return 1;
}
else return 0;
}

int del_list(char* name)
{
eintrag aux=search_list(name);
if(aux!=NULL)            //zu löschender eintrag überhaupt vorhanden?
{
if(aux==start)start=aux->next;        //element rauslöschen, besondere hand
else aux->before->next=aux->next;     //habung am listenanfang und -ende
if(aux->next!=NULL)aux->next->before=aux->before;
free(aux->name);      //verwendeten speicher wieder freigeben
free(aux->nr);
free(aux);
return 1;
}
return 0;
}


eintrag search_list(char *name)
{
strupr(name);
for(eintrag p=start;p;p=p->next)   //durch die liste gehen
{
if(strcmp(name,p->name)==0)return p;  //strings vergleichen
}
return NULL;
}

int alph_cmp(eintrag e1, eintrag e2)    //alph. vergleichen
{
if(strcmp(e1->name,e2->name)>0)return 1;
if(strcmp(e1->name,e2->name)<0)return 0;
return 0;
}

void print_list()
{
int anzahl=0;
for(eintrag p=start;p;p=p->next)  //durch die liste gehen
{
print_entry(p);    //print_entry druckt einzelnes listenelement
anzahl++;
}
printf("\n\n%d Einträge vorhanden.",anzahl);
}

void print_entry(eintrag entry)
{


printf("\n%s, %s",entry->name, entry->nr);
}


void * alloc(int size)        //speicher für listenelement holen
{                             //dynamische speicherverwaltung
void * mem =  malloc(size);   //nur so viele listeneinträge wie gebraucht werden
if(mem == NULL)               //werden auch im speicher belegt
	{
	printf("Speicherallokation fehlgeschlagen, abbruch!");
		  exit(1);
	}
return mem;
}
