Problem mit Verständnis von Code
-
Hallo und zwar fand ich eben folgenden Code im Internet:
#include <stdio.h> #include <string.h> char rot13c(char c) { char u[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char l[] = "abcdefghijklmnopqrstuvwxyz"; char *p; if ((p = strchr(u, c)) != NULL) return u[((p-u) + 13) % 26]; else if ((p = strchr(l, c)) != NULL) return l[((p-l) + 13) % 26]; else return c; } int main(void) { int c; while ((c = getchar()) != EOF) putchar(rot13c(c)); }
Nur leider habe ich einige Probleme diesen Code zu verstehen.
Ich weiß das dieser Code als Ausgabe etwas verschlüsseltes ausgibt.
Könnte mir jemand den Code Zeile für Zeile erklären?
Wäre euch echt sehr dankbar.
-
Hi,
werd mal versuchen zu erklären was in der Funktion passiert.
Zuerst werden zwei char Arrays(u,l) mit dem Alphabet initialisiert,
einmal in groß- und einmal in kleinschreibung. Danach wird ein
Pointer(p) auf ein char deklariert.So jetzt erst mal zu der Funktion strchr(), diese bekommt eine
Zeichenkette und ein einzelnes Zeichen übergeben und überprüft
dann ob das einzelne Zeichen in der Zeichenkette enthalten ist.
Ist das der Fall, gibt sie einen Pointer auf genau dieses
Zeichen zurück. Ist das nicht der Fall wird ein NULL-Pointer
zurückgegeben.So jetzt weiter mit deiner Funktion, diese bekommt ja ein Zeichen
übergeben. Mit der if-else wird nun überprüft ob dieses Zeichen
in dem Array(u) oder in dem Array(l) enthalten ist also ob es groß-
oder kleingeschrieben ist, wenn es in keinem der beiden Arrays(u,l)
enthalten ist wird einfach das eingegebene Zeichen wieder zurück
gegeben.Ok, jetzt fehlt nur noch die Zeile mit dem ((p-u)+13)%26.
Mit p-u bekommst du die Stelle in deinem Array an dem das
eingebene Zeichen zu finden ist, also wenn du z.B. ein A eingeben
hast ergibt p-u = 0 denn das A ist an der 0ten Stelle in deinem
Array. Zu dem Ergebnis von p-u wird nun 13 addiert.Warum aber 13? Weil 13 genau die hälfte der länge deines Arrays ist
und somit gewähleistet wird das die zeichen auch wieder korrekt
zurück konvertiert werden. Das %26 ist dafür gedacht das es keinen
Überlauf gibt, denn wenn du z.B ein Z eingibst ergibt p-u = 25 dieses dann
+13 also 25+13 ergibt 38 und das gäbe einen Überlauf denn in deinen
Arrays(u,l) gibt es nur 26 Stellen(0-25). Durch das %26 wird in unserem
Beispiel nun aus der 38 eine 12, denn die 38 geht 1mal in die 26 und es
bleiben 12 übrig, aber wie der Modulo funktioniert weißt du ja bestimmt.Das war eigentlich alles was die Funktion macht, zeige es dir aber jetzt
nochmal ein wenig anschaulicher.Beispiel:
Du gibts ein A ein
p-u = 0 0+13 = 13 13%26 = 13
Also landes du an der Stelle 13 in deinem Array und das ist das N
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z *--------------------------->*
und wieder zurück.
du gibst ein N ein
p-u = 13 13+13 = 26 26%26 = 0
und landes wieder bei Stelle 0 also bei dem A
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ->* *-------------------------------------
Hoffe erklärung war einigermaßen verständlich.
gruß smilingman
-
smilingman schrieb:
Hoffe erklärung war einigermaßen verständlich.
ja.
-
#include <stdio.h> #include <string.h> char rot13c(char c) { char u[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char l[] = "abcdefghijklmnopqrstuvwxyz"; char *p; if ((p = strchr(u, c)) != NULL) return u[((p-u) + 13) % 26]; else if ((p = strchr(l, c)) != NULL) return l[((p-l) + 13) % 26]; else return c; } void rot13(char *buf, const char *in) { while (*in) { *buf++ = rot13c(*in++); printf ("buf == %c\n",buf); printf ("in == %c\n",in); } *buf = 0; } int main(void) { char fmt[256]; rot13(fmt, "Grfg \r\n"); /* Test */ printf ("%s",fmt); system ("PAUSE"); return 0; }
Habe eine erweiterung des Code's gefunden.
Konnte mir grade jemand die Funktion "rot13" erklären?
-
bist du sicher das programmieren lernen was für dich ist?
erst soll man dir den code "zeile für zeile" erklären (was jemand auch noch macht?), und dann kannst du noch nicht mal mit einer suchmaschine nach rot13 suchen.das dauert nicht mal 10 sekunden mit tippen und enter drücken.
-
Ehrlich gesagt lege ich keinen Wert auf deine Meinung.
Ich will das nur mit den Zeigern erklärt kriegen.
Weil als Ausgabe von buf und in erhalte ich immer folgendes:buf == q in == L buf == r in == M buf == s in == N buf == t in == O buf == u in == P buf == v in == Q buf == w in == R buf == x in == S buf == y in == T
Und das kann ich mir nicht so wirklich erklären.
Das sind jetzt 6 Zeilen könnte nicht jemand mir das schnell erklären?
-
Learning by Doing heißt hier die Devise.
Ist so gut wie selbst erklärend wie ich finde.Weißt du denn was Zeiger und Arrays sind?
Wenn nicht, lernen.In den FAQs gibt es Tutorials zum Lernen.
Erst fordern und dann betteln ist in den wenigsten Foren gerne gesehen.
Wie weit bist du denn schon selber gekommen?
Was verstehst du denn nicht?
-
NullPunktEins schrieb:
Ehrlich gesagt lege ich keinen Wert auf deine Meinung.
Ich will das nur mit den Zeigern erklärt kriegen.Nette Umgangsformen, die du hier im Forum pflegst. Du solltest erst einmal richtig C++ lernen und nicht versuchen, einzelne Codefetzen zu verstehen, die du irgendwo im Internet findest.
Falls du dann immer noch nicht weiter kommst, kannst du hier ja fragen. Zeig dann aber auch Eigeninitiative und behandle die Leute mit Respekt.
-
Also ich weiß sehr wohl was Zeiger & Array's sind.
Nur ich muss zugebene ich habe einige Probleme mit Zeigern.
Ich würde eigentlich nur gerne wissen wie fmt den entschlüsselden Wert von dem Zeiger bekommt.
Ich weiß das der Zeiger buf auf fmt "zeigt".
Aber mehr verstehe ich auch nicht.
Die folgenden Zeilen verstehe ich nicht so wirklich:while (*in) { *buf++ = rot13c(*in++);
Ok ne while Schleife wird gestartet aber wann wird sie beendet?
Und wie ist das mit *buf++ und der Parameter der rot13c übergeben wird (*in++)?
-
NullPunktEins schrieb:
Ok ne while Schleife wird gestartet aber wann wird sie beendet?
wenn (*in == 0)
NullPunktEins schrieb:
Und wie ist das mit *buf++ und der Parameter der rot13c übergeben wird (*in++)?
*buf wird ein wert (der rückgabewert der funktion rot13c()) zugewiesen, danach mit ++ inkrementiert, zeigt danach also auf das nächste byte im speicher. das selbe passiert mit *in als eingabepuffer.
-
zeigt danach also auf das nächste byte im speicher
Ah des heißt also fmt[0] = *buf++ = fmt[1]?
Habe ich das jetzt richtig verstanden?
-
nunja, eher
a = *buf; -> a == buf[0] a = *buf++; -> a == buf[1]
usw.
man hätte es auch so:
int i = 0; while (in[i]) { buf[i] = rot13c(in[i]); i = i + 1;
schreiben können
-
Ok ich danke dir.
Thread kann geschlossen werden.
-
Hallo ich weiß das Thema ist schon alt aber diese Zeile kann doch nicht stimmen:
return u[((p-u) + 13) % 26];
Wenn man mal Beispiel's Weise ein N eingibt 13 Buchstabe im Alphabet und dann (13-26) + 13 macht kommt man auf 0.
Oda verstehe ich dar was verkehrt?
-
Learning by Burning ...
-
Das beantwortet meine Frage immer noch nicht.
-
Hallo,
KeyMaster schrieb:
Wenn man mal Beispiel's Weise ein N eingibt 13 Buchstabe im Alphabet und dann (13-26) + 13 macht kommt man auf 0.
Oda verstehe ich dar was verkehrt?Ja, denn dass der Klammerausdruck negativ wird, kann nie passieren, da u auf den ersten Buchstaben verweist, also auf das "A". Wird z.B. das "N" gefunden, dann liegt das sicher "hinter" dem "A", also p > u in diesem Fall (und p = u, wenn nach dem "A" gesucht wurde).
MfG,
Probe-Nutzer