#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

struct Knoten
{
	char Ziffer;
	struct Knoten *Nachfolger;
	struct Knoten *Vorgaenger;
};

/*------------------------------------------*/

struct Listenkopf
{
	struct Knoten *anfang;
	struct Knoten *ende;
};

/*------------------------------------------*/


struct Listenkopf *Listeanlegen(void)
{
	struct Listenkopf *kopf=(struct Listenkopf*)(malloc(sizeof(struct Listenkopf)));
    
	if(kopf)
	{
		kopf->anfang=0;
		kopf->ende=0;
		return(kopf);
	}
    
	return(0);
}

/*------------------------------------------*/


int Anhaengen(struct Listenkopf *kopf, char ziff)
{
	struct Knoten *haengean=(struct Knoten*)(malloc(sizeof(struct Knoten)));
   
	if(haengean)
	{
		haengean->Ziffer=ziff;
		haengean->Nachfolger=0;
		haengean->Vorgaenger=kopf->ende;
     
		if(!(kopf->anfang))
		{
			kopf->anfang=haengean;
			kopf->ende=haengean;
		}
		else  
		{
			kopf->ende->Nachfolger=haengean;
			kopf->ende=haengean;
		}    
		return(1);
	}
   
	return(0);
}

/*------------------------------------------*/

int VorneAnhaengen(struct Listenkopf *kopf, char ziff)
{
	struct Knoten *haengean=(struct Knoten*)(malloc(sizeof(struct Knoten)));
   
	if(haengean)
	{
		haengean->Ziffer=ziff;
		haengean->Vorgaenger=0;
		haengean->Nachfolger=kopf->anfang;
     
		if(!(kopf->anfang))
		{
			kopf->anfang=haengean;
			kopf->ende=haengean;
		}
		else  
		{
			kopf->anfang->Vorgaenger=haengean;
			kopf->anfang=haengean;
		}    
		return(1);
	}
   
	return(0);
}


/*------------------------------------------*/


void VorwaertsAnzeigen(struct Listenkopf *kopf)
{
	struct Knoten *aktuell=kopf->anfang;
  
	if(!aktuell)
	{
		printf("Sie hatten keine Zahl eingegeben.\n"); 
		return;
	}
    
    /*printf("Ihre eingegebene Zahl:\n");*/
	while(aktuell)
	{ 
		printf("%c",aktuell->Ziffer); 
		aktuell=aktuell->Nachfolger;
	}
	printf("\n");
	return;
}




/*------------------------------------------*/


void Addieren(struct Listenkopf *kopf1, struct  Listenkopf *kopf2,struct  Listenkopf *kopf3)
{
	struct Knoten *aktuell1=kopf1->ende;
	struct Knoten *aktuell2=kopf2->ende;
	int ziffer1=0, ziffer2=0,uebertrag=0;
	char neuereintrag='0';
  
	if(!aktuell1 || !aktuell2)
		return; 
  
	while(aktuell1 || aktuell2) // Hauptschleife zur Addition, solange Ziffern vorhanden
	{
		if(aktuell1)
		{
			switch(aktuell1->Ziffer)
			{
				case '0':  ziffer1=0; break;
				case '1':  ziffer1=1; break;
				case '2':  ziffer1=2; break;
				case '3':  ziffer1=3; break;
				case '4':  ziffer1=4; break;
				case '5':  ziffer1=5; break;
				case '6':  ziffer1=6; break;
				case '7':  ziffer1=7; break;
				case '8':  ziffer1=8; break;
				case '9':  ziffer1=9; break;
	  
			}
		}
		else
		{
			ziffer1=0;
		}
      
      
      
		if(aktuell2)
		{
			switch(aktuell2->Ziffer)
			{
				case '0':  ziffer2=0; break;
				case '1':  ziffer2=1; break;
				case '2':  ziffer2=2; break;
				case '3':  ziffer2=3; break;
				case '4':  ziffer2=4; break;
				case '5':  ziffer2=5; break;
				case '6':  ziffer2=6; break;
				case '7':  ziffer2=7; break;
				case '8':  ziffer2=8; break;
				case '9':  ziffer2=9; break;
	  
			}
		}
		else
		{
			ziffer2=0;
		}
      
      
		switch((ziffer1+ziffer2+uebertrag))
		{
			case 0: uebertrag=0; neuereintrag='0';break;
			case 1: uebertrag=0; neuereintrag='1';break;
			case 2: uebertrag=0; neuereintrag='2';break;
			case 3: uebertrag=0; neuereintrag='3';break;
			case 4: uebertrag=0; neuereintrag='4';break;
			case 5: uebertrag=0; neuereintrag='5';break;
			case 6: uebertrag=0; neuereintrag='6';break;
			case 7: uebertrag=0; neuereintrag='7';break;
			case 8: uebertrag=0; neuereintrag='8';break;
			case 9: uebertrag=0; neuereintrag='9';break;
			case 10: uebertrag=1; neuereintrag='0';break;
			case 11: uebertrag=1; neuereintrag='1';break;
			case 12: uebertrag=1; neuereintrag='2';break;
			case 13: uebertrag=1; neuereintrag='3';break;
			case 14: uebertrag=1; neuereintrag='4';break;
			case 15: uebertrag=1; neuereintrag='5';break;
			case 16: uebertrag=1; neuereintrag='6';break;
			case 17: uebertrag=1; neuereintrag='7';break;
			case 18: uebertrag=1; neuereintrag='8';break;
			case 19: uebertrag=1; neuereintrag='9';break;
	
		}
      
      
      
		if(!VorneAnhaengen(kopf3, neuereintrag)) printf("Fehler!\n");
     
		if(aktuell1)   aktuell1=aktuell1->Vorgaenger;

		if(aktuell2)  aktuell2=aktuell2->Vorgaenger;
        
	} //Ende Hauptschleife
    
    
	if(uebertrag==1)  //Beruecksichtigung eines evtl. vorhandenen letzten Uebertrags
	{
		neuereintrag='1';
		if(!VorneAnhaengen(kopf3, neuereintrag)) printf("Fehler!\n");
	}
    
	return;
  
}





/*------------------------------------------*/



void Loeschen(struct Listenkopf *kopf)
{
	struct Knoten *aktuell=kopf->anfang, *nachf;
  
	while(aktuell)
	{ 
		nachf=aktuell->Nachfolger;
		free(aktuell);
		aktuell=nachf;
	}
	free(kopf);
  
}

/*------------------------------------------*/

int main(void)
{
	struct Listenkopf *liste1, *liste2, *liste3;
	char eingabe='0';
  
	liste1=Listeanlegen();
	liste2=Listeanlegen();
	liste3=Listeanlegen();
  
	printf("Dieses Programm kann beliebig lange natuerliche Zahlen addieren.\n\n");
  
	printf("Sie koennen nun Ihre erste beliebig lange natuerliche Zahl ziffernweise von links nach rechts eingeben.\n\
Die Eingabe jeder Ziffer schliessen Sie mit der \"return\"-Taste ab.\nSobald Sie ein anderes Zeichen eingeben, wird die Eingabe beendet.\n");
  
	while(isdigit(eingabe) )
	{
		scanf("%c",&eingabe);
		getchar();
		if(isdigit(eingabe) )
		{
			if(!(Anhaengen(liste1,eingabe)))
			{
				printf("Ziffer konnte nicht geschrieben werden.\n");
			}
		}
	}
    
	eingabe='0'; 
	printf("Geben Sie nun genauso Ihre zweite Zahl ein.\n"); 
    
	while(isdigit(eingabe) )
	{
		scanf("%c",&eingabe);
		getchar();
		if(isdigit(eingabe)  )
		{
			if(!(Anhaengen(liste2,eingabe)))
			{
				printf("Ziffer konnte nicht geschrieben werden.\n");
			}
		}
	}  
  
	printf("Erste eingegebene Zahl:\n");
	VorwaertsAnzeigen(liste1);
  
 
	printf("Zweite eingegebene Zahl:\n");
	VorwaertsAnzeigen(liste2);
 
	Addieren(liste1,liste2,liste3);
  
	printf("Deren Summe:\n");
	VorwaertsAnzeigen(liste3);
  
  
  
  
	Loeschen(liste1);
	Loeschen(liste2);
	Loeschen(liste3);
    
	return(0);
   
}

