/*
  Autor : Lampacher Martin
  Datum : 20/10/05
  Fach  : Systeme
*/
#include <stdio.h>
#include <conio.h>

/*
  Ueberprueft, ob der eingegebene String
  numerisch ist (also NUR aus Zeichen
  von 0-9 besteht). Sie liefert 1 bei
  einem numerischen, 0 bei einem nicht
  numerischen String
*/
int ist_numerisch (char *str) {
  int ok = 1;
  /* wird nur so lange ausgefuehrt, bis ein nicht
     numerisches Zeichen gefunden wurde (ok wird
     dann auf 0 gesetzt) oder bis der String komplett
     durchlaufen wurde 				      */
  while ((*str) && (ok)) {
    switch (*str) {
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      /* Es existiert kein break bei den vorhergehenden,
	 da sie gleich behandelt werden sollten wie eine 9
	 ist als ob man in Pascal '0','1'... schreibt      */
      case '9': break;
      /* Zeichen war keine Zahl -> Ueberpruefung wird
	 abgebrochen					   */
      default : ok = 0;
    }
    str++;
  }
  return ok;
}

/* Wandelt den String1 (*str1) in Grossbuchstaben um und
   loest  auf, Sonderzeichen werden uebernommen. Der
   umgewandelte String wird in *str2 gespeichert  	  */
void gross_buchst (char *str1, char *str2) {
  int geaendert = 0;
  /* nur solange der String vorhanden ist */
  while (*str1) {
    geaendert = 0;
    /* ueberprueft, ob das Zeichen im Bereich der Klein-
       buchstaben liegt. Falls schon, wird dieser in einen
       Grossbuchstaben umgewandelt und geaendert auf 1 ge-
       setzt, damit das umgewandelte Zeichen nicht nochmal
       umgewandelt wird					  */
    if ((*str1>= 'a') && (*str1<='z')) {
      *str2 = *str1 + ('A' - 'a');
      geaendert = 1;
    }
    if (!(geaendert)) {
      geaendert = 1;
      /* Ueberpruefen, ob es ein aufzuloesendes Sonder-
	 zeichen ist					*/
      switch (*str1) {
	case '' :
	case '' : *str2++ = 'A';
		   *str2 = 'E';
		   break;
	case '' :
	case '' : *str2++ = 'O';
		   *str2 = 'E';
		   break;
	case '' :
	case '' : *str2++ = 'U';
		   *str2 = 'E';
		   break;
	case '' : *str2++ = 'S';
		   *str2 = 'S';
	default  : geaendert = 0;
      }
      /* Wenn keines der oberen zutrifft, dann handelt es
	 sich um ein Sonderzeichen oder um einen bereits
	 gross geschriebenen Buchstaben			  */
      if (!(geaendert)) {
	*str2 = *str1;
      }
    }
    str1++;
    str2++;
  }
  /* man muss noch ein \0 als Endezeichen setzen          */
  *str2 = '\0';
}

/* Sucht im str1 nach Zeichen, die in str3 schon vorhanden
   sind. Alle Zeichen ungleich einem Zeichen in str3 werden
   in str2 kopiert					    */
void str_compress (char *str1, char *str2, char *str3) {
  int ok;
  int i;
  while (*str1) {
    ok = 1;
    i = 0;
    /* Ueberpruefen ob ein Zeichen gleich einem von str3 ist */
    while ((ok) && (*str3)) {
      if (*str1 == *str3++) {
	ok = 0;
      }
      else {
	i++;
      }
    }
    /* Man muss den Zeiger wieder zurueckzaehlen, damit auch
       beim zweiten Buchstaben von str1 noch korrekt ueber
       prueft ist				              */
    while (i != 0) {
      str3--;
      i--;
    }
    /* Nur wenn er nicht gleich ist, wird in str2 kopiert */
    if (ok) {
      *str2 = *str1;
      str2++;
    }
    str1++;
  }
  /* Das Endezeichen fuer den String anhaengen */
  *str2='\0';
}

/* Dreht str1 um und speichert ihn in str2     */
void str_reverse (char *str1, char *str2) {
  int i = 0;
  /* Zhlen bis zum Ende des Strings um vom Ende
     bis zum Anfang laufen zu knnen            */
  while (*str1) { i++; str1++; }
  while (i != 0) {
    *str2++ = *--str1;
    i--;
  }
  /* Endezeichen anhaengen */
  *str2 = '\0';
}

/* Ueberprueft ob str ein Palindrom ist. Gibt 0 bei false
   zurueck und 1 falls es sich um ein Palindrom handelt.
   ACHTUNG Case-Sensitive			          */
int ist_palindrom (char *str) {
  char str1[40];
  /* Den String umdrehen */
  str_reverse  (str,str1);
  /* Den String mit dem Umgedrehten vergleichen,
     dann den enstprechenden Rueckgabewert liefern */
  if (!(strcmp(str,str1))) {
    return 1;
  }
  else {
    return 0;
  }
}
void main (void) {
  int back;
  /* ch ist die Abbruchbedingung fuer das Programm */
  char ch='a';
  /* Verschiedene Strings, um auch den String, der
     eingegeben wurde noch verfuegbar ist          */
  char str1[20];
  char str2[40];
  char str3[20];

  /* Solange nicht b gedrueckt wird, wird das Programm
     immer wieder wiederholt			       */
  while (ch != 'b') {
    clrscr();
    printf ("Eingabe Pruefstring : ");
    scanf("%s",str1);/*
    printf ("Eingabe Sonderzeichenstring : ");
    scanf("%s",str3);  */
    /*back = ist_numerisch(str1);
    gross_buchst(str1,str2);
    printf ("Der String %s ist %d\n",str1,back);
    printf ("Der String %s ist in Grossbuchstaben %s\n",str1,str2);
    str_compress (str1,str2,str3);
    printf ("String %s ohne Sonderzeichen %s : %s",str1,str3,str2);
    str_reverse (str1,str2);
    printf ("Der String %s lautet umgekehrt %s",str1,str2);        */
    if (ist_palindrom(str1)) {
      printf ("Der String %s ist ein Palindrom\n",str1);
    }
    else {
      printf ("Der String %s ist kein Palindrom\n",str1);
    }
    ch = getch();
  }
}

