/* pruefstr.c bzw. loe017c.html
   Loesung der Aufgabe Pruefsumme berechnen
   Themen: Zeichenketten, File I/O, Funktionen, Datenuebertragung
   Um die korrekte Uebertragung von Daten zu ueberpruefen, wird oft
   eine Pruefsumme berechnet und an die Daten ahgehaengt. Nach der
   Ubertragung wird die Pruefsumme erneut berechnet und kontrolliert.
   In diesem Beispiel soll fuer eine Zeichenkette eine Pruefsumme 
   berechnet werden (Summe der Ascii-Codes der Zeichen modulo 256),
   und an die Zeichenkette angehaengt werden. Eine Funktion soll dann
   eine eventuell fehlerhafte Uebertragung simulieren. 
   Eine weitere Funktion prueft dann die Pruefsumme und entfernt sie wieder.
*/

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

/* damit die Pruefsumme wieder als Ascii-Zeichen darstellbar ist, 
   muss sie im Bereich 0 bis 127 liegen */
#define MODULUS 128  

/* Prototypen fuer die Funktionen */

int pruefsumme_erzeugen (char *s);
int pruefsumme_entfernen (char *s);
void uebertragung (char *s);


int main(void)
{
  FILE *fin;
  char s[50];
  int psumme;
  int status;


  if ( (fin = fopen("pruefstr.in", "r")) == NULL) {
    printf("Fehler beim Oeffnen der Datei pruefs.in\n");
    exit(1);
  }

  while ( fscanf(fin, "%s", s) != EOF ) {
    printf("%-20s  ", s);
    psumme = pruefsumme_erzeugen(s);
    printf("%3i  ", psumme);
    uebertragung(s);
    status = pruefsumme_entfernen(s);
    if (status)
      printf("%-20s Fehler\n", s);
    else
      printf("%-20s OK\n", s);
  }
  fclose(fin);

  getchar();

  return 0;

} /* end main */


int pruefsumme_erzeugen (char *s) 
{
  int i, laenge;
  int summe;

  laenge = strlen(s);

  summe = 0;
  for (i = 0; i < laenge; i++)
    summe = summe + s[i];   /* s[i] ist der Code des i-ten Zeichens */
  summe = summe % MODULUS;

  /* Pruefsumme anhaengen: 
     die Position des Abschlusszeichens '\0' der Zeichenkette ist laenge */
  s[laenge] = summe;
  s[laenge+1] = '\0';
  return summe;
}

  
int pruefsumme_entfernen (char *s) /*
---------------------------------------------------------------
ueberprueft und entfernt die Pruefsumme
--------------------------------------------------------------*/
{
  int i, laenge;
  int summe;

  laenge = strlen(s);  /* ist jetzt um ein Zeichen laenger */
  laenge--;            /* deshalb ziehen wir 1 ab           */

  summe = 0;
  for (i = 0; i < laenge; i++)
    summe = summe + s[i];   /* s[i] ist der Code des i-ten Zeichens */
  summe = summe % MODULUS;

  /* Pruefsumme ueberpruefen und "entfernen": */
     
  if (s[laenge] == summe) {
    s[laenge] = '\0';
    return 0; /* kein Fehler */
    }
  else {
    s[laenge] = '\0';     
    return 1; /* Fehler */
  }
 
} /* end pruefsumme_entfernen */

void uebertragung (char *s) /*
-------------------------------------------------------------------------
erzeugt zufaellige "Uebertragungsfehler"
-----------------------------------------------------------------------*/
{
  int laenge, pos;

  laenge = strlen(s) - 1;  
  /* die Pruefsumme selber soll nicht veraendert werden */
  /* zufaellige Position im Bereich 0 bis 4-fache Wortlaenge erzeugen */
  pos = 4 * (rand() % laenge);
  if (pos < laenge)
    s[pos] = rand() % 128;  /* zufaelliges Zeichen erzeugen -> Fehler */
}


/* Beispiel fuer eine Datei pruefstr.in
-----------------
Vivaldi
Rossini
Mozart
Haydn
Gulda
Jarrett
-----------------
*/