Zeichen in einem Array in ihren ASCII-Code unmwandeln (und zurück)



  • Hallo, ich bin noch ein ziemlich blutiger C++-Noob, mein erstes eigenes Programm soll ein Verschlüsselungstool für den Caesar-Code werden. (Falls den jemand nicht kennt: Man tauscht jeden Buchstaben durch einen aus der im Alphabet um eine bestimmte Menge Stellen weiter vorne oder hinten steht.)
    Dafür bräuchte ich nun eine Funktion, die es mir erlaubt, in dem Array in das der Benutzer den Text eingegeben hat, einfach alle Zeichen in ASCII-Code (oder auch sonst in irgendwelche beliebige Zahlen) umzuwandeln mit denen ich dann rechnen könnte.
    Ich habe mit auch überlegt, Nullterminierte Strings für die Eingabe der Texte zu verwenden, um die Speicherbenutzung besser zu verwalten, aber wäre es dann nicht so, dass wenn in dem Text irgendwo eine Null vorkommt, der Text als beendet angesehen würde?

    Danke schonmal, Tetrapak



  • Nullterminierte Strings werden durch ASCII 0, nicht die Ziffer 0 (= ASCII 48) abgeschlossen. Wenn du den Text als char-Array (also einen C-String) hast, dürfte es am einfachsten sein, auf die einzelnen Werte zuzugreifen und diese zu bearbeiten. Wie das genau geht kannst du einem der vielen vielen Tutorials entnehmen 😉



  • Hi
    Wenn du einzelne Chars hast, kannst du damit einfach rechnen

    text[i] += 5;
    

    Verschiebt den Buchstaben um 5 Zeichen nach hinten.
    Nullterminierte Strings enden mit '\0' nicht mit '0'. Also kein Problem.
    Aber wenn du mit std::strings arbeiten willst, dann brauchst du den Null-Terminus gar nicht.



  • Tetrapak schrieb:

    Hallo, ich bin noch ein ziemlich blutiger C++-Noob, mein erstes eigenes Programm soll ein Verschlüsselungstool für den Caesar-Code werden. (Falls den jemand nicht kennt: Man tauscht jeden Buchstaben durch einen aus der im Alphabet um eine bestimmte Menge Stellen weiter vorne oder hinten steht.)
    Dafür bräuchte ich nun eine Funktion, die es mir erlaubt, in dem Array in das der Benutzer den Text eingegeben hat, einfach alle Zeichen in ASCII-Code (oder auch sonst in irgendwelche beliebige Zahlen) umzuwandeln mit denen ich dann rechnen könnte.

    int main( void )
    {
      char * eingabe = "Eingabe";
      char   asciiZeichen;           // Zeichen oder Zahl zwischen -128..127
    
      asciiZeichen = eingabe[0];
    
      printf( "String: %s   Zeichen 0: %c    ASCII-Code: %d\n", eingabe, asciiZeichen, asciiZeichen );
    
      return 0;
    }
    

    Eingaben/Strings werden (für Dich erstmal) grundsätzlich als ASCII-Code gespeichert.

    Tetrapak schrieb:

    Ich habe mit auch überlegt, Nullterminierte Strings für die Eingabe der Texte zu verwenden, um die Speicherbenutzung besser zu verwalten, aber wäre es dann nicht so, dass wenn in dem Text irgendwo eine Null vorkommt, der Text als beendet angesehen würde?

    So macht man das in C/C++ üblicherweise auch.

    int main( void )
    {
      char * eingabe = "Eingabe";  // Eingabe + Nullbyte!
    
      int i = 0;
    
      while( eingabe[i] != '\0' )
        i++;
    
      printf( "Länge: %d\n", i );
    }
    

    Mein Tipp: Kauf Dir ein C (nicht C++) Buch.
    Lern erst etwas programmieren, bevor Du beginnst Programme zu designen (OOP, dafür braucht man C++, nicht zum Programmieren, das macht man weiterhin in C)



  • Gut, ich hab mich jetzt mal dran versucht und mein Ergebnis sieht bis jetzt so aus

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<string>
    using namespace std;
    
    int main( void )
    {
    string Text;
    int i=0;
    cout << "Geben sie Text ein\n";
    cin >> Text;
    
        while (Text[i] != '\0')
        {
        Text[i] += 3;
        ++i;
        }
    
    cout << " Der codierte Text lautet" << Text << "\n";
    system ("PAUSE");
    return 0;
    }
    

    Leider kann ich das grade nicht überprüfen weil mein Compiler sich mit dem Computer streitet und im Sekundentakt schwere Ausahmefehler meldet. Was den Tipp mit dem Buch angeht, das habe ich bereis getan und bin auch schon halb durch damit. Nur ist es halt immer schwer, das erste eigene Programm zum Laufen zu bringen.



  • Tetrapak schrieb:

    Gut, ich hab mich jetzt mal dran versucht und mein Ergebnis sieht bis jetzt so aus

    [...s.o....]

    Leider kann ich das grade nicht überprüfen weil mein Compiler sich mit dem Computer streitet und im Sekundentakt schwere Ausahmefehler meldet.

    Vielleicht solltest Du einen anderen Compiler nehmen... das klingt nicht sonderlich vertrauenserweckend!?

    Wenn man die katastrophale Einrückung mal übersieht, sieht es doch ganz nett aus.
    Noch eine Abfrage rein, damit x wieder zu a wird usw...

    Tetrapak schrieb:

    Was den Tipp mit dem Buch angeht, das habe ich bereis getan und bin auch schon halb durch damit. Nur ist es halt immer schwer, das erste eigene Programm zum Laufen zu bringen.

    Mehr oder weniger. string, namespaces, cin und cout sind nicht grade C Eigenschaften 😉
    Egal... Lerne erstmal richtig(!) mit Schleifen und Operatoren klarzukommen, bevor Du namespaces, classes und templates versuchst.

    Das mag für manche am Anfang langweilig sein, aber man wird kein Software Designer, wenn man die einfachsten Grundlagen nicht wirklich perfekt kennt.



  • Bist du sicher, das std::string nullterminiert ist? Mach es besser so

    for( int i=0; i<Text.size(); ++i')
    {
      Text[i] += 3;
    }
    


  • Mehr oder weniger. string, namespaces, cin und cout sind nicht grade C Eigenschaften 😉
    Egal... Lerne erstmal richtig(!) mit Schleifen und Operatoren klarzukommen, bevor Du namespaces, classes und templates versuchst.

    Mir wäre nicht bewusst, dass ich da jemals versucht hätte ;-). Das Programm ist doch nun wirklich einfacdh genug dass man damit anfangen kann und mit Templates usw. habe ich mich noch gar nicht beschäftigt. Eigntlich ist das Buch was ich grade lese ein Buch über C++ aber ich habe eben erst die erste Hälfte gelesen und in diesem Teil ist von OOP erstmal noch nicht die Rede.

    Was die Einückung angeht: Wieso sollte die so katatrophal sein?



  • Sorry für den Doppelpost, aber ansonsten sieht man ja leider gar nicht dass sich was geändert hat. Es hat sich mittlerweile ein neues Problem ergeben: Ich würde gerne die Ergbnisse meines mittlerweile funktionierenden Algorithmus per Mail verschicken. Da ich aus der DOS-Eingabeaufforderung nichts rauskopieren kann, bräuchte ich einen Befehl, der den Text-String in einer txt-Datei abspeichert von wo ich dann weitermachen kann.

    Weiteres Problem: Obwohl es ja eigentlich sinnlos ist, hätte ich gern die Möglichkeit, nicht nur 3 oder 5 zu addieren sondern auch etwa 150. Da ich dann aber beispielsweise beim ü schon längst aus dem ASCII-Zeichensatz und der Kapazität einer char-Variable draußen bin, dürfte das doch eigentlich nicht gehen oder? Wie kann ich das Problem lösen?



  • Tetrapak schrieb:

    Mir wäre nicht bewusst, dass ich da jemals versucht hätte ;-). Das Programm ist doch nun wirklich einfacdh genug dass man damit anfangen kann und mit Templates usw. habe ich mich noch gar nicht beschäftigt. Eigntlich ist das Buch was ich grade lese ein Buch über C++ aber ich habe eben erst die erste Hälfte gelesen und in diesem Teil ist von OOP erstmal noch nicht die Rede.

    Das ist gut so, aber was ich meine ist, dass Du damit auch nicht zu früh anfangen solltest. C++ bietet viele Hilfen, um Programme gut zu organisieren, aber die Algorithmen werden weiterhin in C geschrieben. Wer also leistungsfähige Algorithmen programmieren möchte, sollte sich sich in C sehr gut auskennen. Das wollte ich sagen.

    Tetrapak schrieb:

    Was die Einückung angeht: Wieso sollte die so katatrophal sein?

    Finde eindeutige Regeln, wann Du einrückst, wie Du einrückst und wann Du davon Ausnahmen machst. Der oben gepostete Sourcecode hat Stellen die eingerückt sind und Stellen in gleicher Ebene, die nicht eingerückt sind. Das mag noch überschaubar sein, wenn das Programm nicht großer als eine Prozedur ist, aber schön ist das nicht.

    Tetrapak schrieb:

    Sorry für den Doppelpost, aber ansonsten sieht man ja leider gar nicht dass sich was geändert hat. Es hat sich mittlerweile ein neues Problem ergeben: Ich würde gerne die Ergbnisse meines mittlerweile funktionierenden Algorithmus per Mail verschicken. Da ich aus der DOS-Eingabeaufforderung nichts rauskopieren kann, bräuchte ich einen Befehl, der den Text-String in einer txt-Datei abspeichert von wo ich dann weitermachen kann.

    Du müsstest die Standardausgabe umleiten. Wie das unter Windows funktioniert, weiß ich nicht. Unter Linux erhältst Du dann einen Stream aus der Du die Ausgabe des Programms wie aus einer Datei herauslesen kannst. Vielleicht kannst Du auch system eine Dateiumleitung mitübergeben und die Datei nachher einlesen?

    Tetrapak schrieb:

    Weiteres Problem: Obwohl es ja eigentlich sinnlos ist, hätte ich gern die Möglichkeit, nicht nur 3 oder 5 zu addieren sondern auch etwa 150. Da ich dann aber beispielsweise beim ü schon längst aus dem ASCII-Zeichensatz und der Kapazität einer char-Variable draußen bin, dürfte das doch eigentlich nicht gehen oder? Wie kann ich das Problem lösen?

    Wo ist das Problem? Die Variable läuft über und fängt von vorne an. Das ist doch genau das, was Du haben willst? Zeichen 125 + 3 ergibt Zeichen -128.
    Wenn Du Probleme mit Druckbaren und Nicht-Druckbaren Zeichen hast, so musst Du die selbstständig abfangen. Du könntest zum Beispiel eine (bzw. zwei für die Rückübersetzung) Codetable einrichten und da nach Belieben verschieben und vertauschen. Das ist für Buchstaben etwas aufwendiger, für Sonderzeichen allerdings einfacher als irrsinig viele ifs oder switchs zu programmieren.



  • Und wie mache ich das genau? Weder in meinem Buch noch in Google habe ich rausfinden können was eine Codetable ist.



  • Tetrapak schrieb:

    Und wie mache ich das genau? Weder in meinem Buch noch in Google habe ich rausfinden können was eine Codetable ist.

    Einfach ein Array ^^

    Es gibt 128 ASCII-Zeichen + 128 Zeichen, die Du ebenfalls verdrehen willst.

    char CodeTable[256];
    
    /* Erstmal bildet jedes Zeichen sich selber ab */
    
    for( int i=0; i<256; i++ )
      CodeTable[i] == i;
    
    /* Salve Caesar! */
    
    for( int i='A'; i < 'W'; i++ )
    {
      CodeTable[ i ]    = i + 3;      // große Buchstaben
      CodeTable[ i|32 ] = (i|32) + 3; // kleine Buchstaben
    }
    
    CodeTable[ 'x' ] = 'a';
    CodeTable[ 'y' ] = 'b';
    CodeTable[ 'z' ] = 'c';
    CodeTable[ 'X' ] = 'A';
    CodeTable[ 'Y' ] = 'B';
    CodeTable[ 'Z' ] = 'C';
    

    Wenn Du jetzt wissen möchtest, wie ein 'a' verschlüsselt wird:

    [cpp]printf( "a ist verschlüsselt ein %c\n", CodeTable[ 'a' ] );[cpp]

    Rückwärts machst Du Dir entweder eine neue Codetable, die ein 'd' wieder in ein 'a' wandelt oder Du suchst in der CodeTable
    die Position, an der Du das 'd' findest. Die Position ist der ASCII-Wert von 'a'. Aber das ist aufwendiger.

    Wenn Du auf Verschlüsselung stehst, kannst Du damit dann auch gleich das Steckbrett der Enigma simulieren.



  • Xin bist du ein Troll?



  • Dr. Prof schrieb:

    Xin bist du ein Troll?

    Nicht, dass ich wüßte.

    Hat diese Frage einen tieferen Hintergrund?



  • Ich wurde mistrauisch als ich mehrfach folgendes gelesen habe:

    xin schrieb:

    Mein Tipp: Kauf Dir ein C (nicht C++) Buch.
    Lern erst etwas programmieren, bevor Du beginnst Programme zu designen (OOP, dafür braucht man C++, nicht zum Programmieren, das macht man weiterhin in C)

    xin schrieb:

    Mehr oder weniger. string, namespaces, cin und cout sind nicht grade C Eigenschaften 😉

    xin schrieb:

    [..]aber die Algorithmen werden weiterhin in C geschrieben.



  • Dr. Prof schrieb:

    Ich wurde mistrauisch als ich mehrfach folgendes gelesen habe:

    xin schrieb:

    Mein Tipp: Kauf Dir ein C (nicht C++) Buch.
    Lern erst etwas programmieren, bevor Du beginnst Programme zu designen (OOP, dafür braucht man C++, nicht zum Programmieren, das macht man weiterhin in C)

    Mehr oder weniger. string, namespaces, cin und cout sind nicht grade C Eigenschaften 😉

    [..]aber die Algorithmen werden weiterhin in C geschrieben.

    Jow, das schrieb ich alles, und da gibt's auch nix dran, was ich nicht so meine.

    Erst lernen, wie man Algorithmen formuliert (und das macht man mit den Elementen, die aus C stammen). Mit Algorithmen erstellt man seine Projekte. Projekte werden größer und bedürfen der Handhabung und Verwaltung von Sourcecodes und Strukturen. Dafür ist C++ sehr hilfreich, da es OOP Programmierung im Vergleich zu C deutlich vereinfacht. Bevor man sich aber über OOP Gedanken macht, sollte man wissen, was man in die Klassen steckt - und dafür braucht man wieder sichere Kenntnisse in C.

    Soweit meine Überzeugung. Ich sehe da nix trolliges dran.



  • Will hier jetzt nicht ewig weit ins OT abdriften und belass es mal dabei.

    Aber überleg dir mal ob das was du hier als C betitelst nicht viel trefflicher als Kontrollstrukturen zu beschreiben wäre und man dies in jedem Einsteigerbuch zu jeder Sprache ganz zu Beginn lernt, lange bevor weiterführende Elemente vorgestellt werden.



  • Neues Problem: Ich habe meinen Caesar-Algorithmus nochmal getestet und gesehen, dass das Programm aufhört, zu codieren sobald in der Benutzereingabe ein Leerzeichen vorkommt. Also wird praktisch immer nur das erste Wort codiert. Lässt sich das irgendwie verhindern?



  • Tetrapak schrieb:

    Neues Problem: Ich habe meinen Caesar-Algorithmus nochmal getestet und gesehen, dass das Programm aufhört, zu codieren sobald in der Benutzereingabe ein Leerzeichen vorkommt. Also wird praktisch immer nur das erste Wort codiert. Lässt sich das irgendwie verhindern?

    Ich vermute Du hast die Eingabe über cin oder scanf ziehst, dann endet die Eingabe bei ' ', aber Du hast noch was im Buffer für das nächste scanf() ^^

    Alternativ hast Du irgendwas im Code, was auf Leerzeichen abfragt und dann abbricht, aber das hättest Du vermutlich selber schon entdeckt 😉


Anmelden zum Antworten