#include #include // Preprocessor-Konstanten werden definiert, der Preprocessor // ersetzt diese dann mit den jew. Werten #define MAXCHRS 5 #define MAXTEXT 200 // Eingabepuffer loeschen... am besten auswendig lernen. // Das "inline" bedeutet nur, dass der Compiler diese // Funktion direkt "einbaut", also ohne Call - ignoriert // es einfach;) void inline clearbuffer() { // Eine leere While-Schleife wird solange durchlaufen // bis ein Newline-Zeichen (CR) kommt. while (getchar() != '\n'); return; } char doreplace(char chr, char *search, char *replace) /* Diese Fkt erwartet ein einzelnes char chr, zwei Pointer auf char-Arrays: search und replace */ { char *search_tmp; // ein Poiner auf ein char wird deklariert if(search_tmp=strchr(search,chr)) /* Die string.h-Funktion strchr gibt die Adresse (also einen Poiner!) des ersten gefundenen Zeichens zurück. Wird das Zeichen nicht gefunden, einen 0-Pointer. Jetzt wird dem Pointer search_tmp diese Adresse zugewiesen - gibt strchr jetzt einen 0-Pointer zurueck, dann wurde nichts gefunden... */ { return *(search_tmp-search+replace); /* Dieser Ausdruck berechnet Adressen IN der Klammer: search_tmp => Adresse des gefundenen Zeichens search => Anfangs-Adresse des zu durchsuchenden char-Arrays +---- Adresse des gefundenen Zeichen | v [CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0] ^ | +---- Anfangsadresse des Arrays | | \--------/ Differenz Wenn man die Pointer-Werte search_tmp von search - also zwei Adressen - voneinander abzieht hat man die Anzahl der dazwischen liegenden Zeichen. Das ist wie ein Array-Index! Jetzt wird dieser Index zur Adresse vom replace- Array addiert und man ist genau beim gewuenschten Zeichen aus dem replace-Array. Die so zusammengebaute Adresse (der Pointer!) wird dereferenziert und liefert das Zeichen. */ } return chr; // Das Originalzeichen, falls es nicht gefunden wurde } int getline(char *query, char *str, int num) /* getline erwartet sich zwei Pointer auf char-Arrays: query und str. (query dient nur der vorherigen Ausgabe eines Strings, wie z.b. "ERSETZEN") - str ist ein Pointer auf ein ausreichend grosses char-Array, wo der eingegebene Text abgespeichert wird. int num ist die Anzahl maximal erlaubter Zeichen. Die Funktion gibt ein int zurueck, dass wird nachher die Anzahl der eingegebenen Zeichen sein. */ { char chr, *str_bak = str; /* Ein char chr und ein char-Pointer str_bak werden deklariert und der str_bak Pointer gleich auf die Adresse von str (dem Ziel-Array) gesetzt. Der Pointer str_bak dient dazu die Anfangsadresse des Arrays zu sichern, damit man sie nachher vergleichen kann... */ printf("%s (%d ZEICHEN)\n", query,num); // Eingabe-Aufforderung printf("S: "); // ... while (666) // Endlos-Schleife { memset(str,0,num-1); /* memset fuellt einen Speicherbereich mit einem bestimmten Wert, hier 0. Das nutze ich im Gegensatz zum Ref-Beispiel damit das Array einen definierten Wert enthaelt und ich ausserdem kein Null-Byte (wie im Ref-Bsp) anhaengen muss :) */ while (( chr=getchar() )!='\n') /* Wiederhole die untere Schleife, bis ein Newline (CR) kommt, und weise das jeweils eingelesene Zeichen gleich chr zu */ { if (str>=str_bak+num) /* Hier findet der Test statt, ob die Array-Grenzen nicht verletzt wurden... Wenn der aktuelle Wert des str-Pointers, (also die Adresse) gr.gl. str_bak (Adresse des Array-Anfangs) und der maximal erlauben Anzahl von Zeichen ist, sind wir am Ende des Arrays und brechen ab: */ { printf("*** MAXIMAL %d ZEICHEN ERLAUBT ***\nS: ", num); str=str_bak; // Der Pointer auf das Ziel-Array wird /* wieder auf den Anfang zurueckgesetzt */ clearbuffer(); // Buffer leeren... break; // innere while-Schleife verlassen } *str=chr; /* Wenn wir noch innerhalb der Array-Grenzen sind, wird das eingelesene Zeichen an die aktuelle Position geschrieben */ str++; //... und der Pointer erhoeht } if (!(str==str_bak)) /* Dieser Test dient dazu festzustellen, ob die gespeicherte Startadresse nicht identisch ist mit der Startadresse des Arrays... Warum? Weil die gleiche Addresse darauf hindeutet, das die Array-Grenzen ueberschritten wurden, denn dabei wird das ja zurueckgesetzt! Wenn die gesicherte Adresse also nicht gleich der aktuellen Adresse ist, wurde etwas erfolgreich eingelesen: */ { str=str_bak; /* Der str-Pointer wird auf den gesicherten Anfang zurueckgesetzt (eigentlich nicht notwendig) return strlen(str); // Die Funktion wird verlassen // mit der Anzahl erfolgreich // eingelesener Zeichen } } } int main() { char search[MAXCHRS+1], repl[MAXCHRS+1], text[MAXTEXT+1], *tmp; // Es werden 3 char-Arrays deklariert sowie ein char-Pointer // Der Pointer wird nachher benutzt, um ueber das Array // zu gehen... getline("SUCHEN",search, MAXCHRS); // Einlese Funktion aufrufen do { getline("ERSETZEN",repl, MAXCHRS); // Einlese Funktion aufrufen } while( strlen(search)!=strlen(repl) ); // Solange der Benutzer nicht gleich viele Zeichen eingegeben // hat, wie im Such-String getline("TEXT",text,MAXTEXT); // Einlesen des Textes durch die Fkt tmp=text; // der tmp-Pointer wird auf die Anfangs-Adresse // des text-Arrays gesetzt printf(" "); while(*tmp) /* so lange der dereferenzierte Pointer (also der Wert "hinter" dem Pointer, auf den der Pointer zeigt) nicht 0 ist - denn 0 ist ja ein String-Ende - wird weitergemacht... */ { putchar(doreplace(*tmp,search,repl)); /* das Zeichen das von doreplace ersetzt wurde wird ausgegeben... */ tmp++; // der Pointer wird erhoeht und zeigt // auf das naechste Zeichen } putchar('\n'); return 0; }