Caesar Verschlüsselung



  • hallo,
    ich muss in c++ eine caesar verschiebung programmieren, allerdings nur mit string und if schleifen. Außerdem sollen Zeichen oder Leerzeichen eingaben nicht verschoben werden, sondern einfach wieder ausgegeben werden.
    Mein Ansatz sah wie folgt aus(dieser funktioniert allerdings nicht und ich finde den Fehler nicht):

    #include <iostream>
    #include <string>
    using namespace std;

    int main()
    {
    string eingabe;
    int ver = 0;
    char buch = 0;
    int i = 0;
    int ver2 = 0;
    int ver3 = 0;

    cout << "Bitte geben Sie den zu verschluesselnden Text ein: ";
    getline(cin, eingabe);
    
    cout << "Bitte geben Sie die Anzahl Verschiebepositionen ein (als positive ganze Zahl): ";
    cin >> ver;
    
    
    while (eingabe.length() > i)
    {
    
    	buch = eingabe.at(i);
    	buch = int(buch);
    
    	if (buch < 65 || buch>90 && buch < 97 || buch>122)
    	{
    		cout << buch;
    		i++;
    		continue;
    	}
    
    	if (buch >= 65 && buch <= 90)
    	{
    		buch = buch + ver;
    
    		while (buch > 90)
    		{
    			ver2 = buch - 90;
    			buch = ver2 + 64;
    		
    		}
    		buch = char(buch);
    		cout << buch;
    		i++;
    		continue;
    
    	}
    
    	if (buch >= 97 && buch <= 122)
    	{
    		buch = buch + ver;
    
    			while (buch > 122)
    			{
    				ver3 = buch - 122;
    				buch = ver3 + 96;
    			}
    		buch = char(buch);
    		cout << buch;
    		i++;
    		continue;
    	}
    }
    cout << endl;
    system("PAUSE");
    return 0;
    

    }



  • funktioniert allerdings nicht

    Das ist keine Fehlerbeschreibung.

    Was hat das mit MFC zu tun?

    Es gibt keine if Schleife.



  • @JK1805 sagte in Caesar Verschlüsselung:

    (dieser funktioniert allerdings nicht und ich finde den Fehler nicht):

    Was ist denn falsch?

    Abgesehen davon ist dein Code viel zu kompliziert.

    1. zu viele Variablen
    2. Schleife über alle Zeichen eines Strings --> for (char ch : the_string) { ... }, nicht while.
    3. Was soll buch = int(buch) bedeuten?
    4. Statt Zahlen wie 65 solltest du 'A' verwenden, das besser lesbarer

    Ich schlage dir folgendes vor:

    #include <iostream>
    #include <string>
    using namespace std;
    
    char verschiebe_buchstaben_in_bereich(char ch, int ver, char from, char to) {
        if (ch >= from && ch <= to) {
            // hier musst du nur noch die Verschiebung einbauen. Geht als Einzeiler,
            // wenn du Modulo benutzt. Hilfestellung: 'A' - 'A' = 0, 'B' - 'A' = 1 usw
            // Aber vielleicht brauchst du ein bisschen mehr.
        }
        return ch;
    }
    
    int main() {
        string eingabe;
        int ver = 0;
        cout << "Bitte geben Sie den zu verschluesselnden Text ein: ";
        getline(cin, eingabe);
        cout << "Bitte geben Sie die Anzahl Verschiebepositionen ein (als positive "
                "ganze Zahl): ";
        cin >> ver;
    
        for (char ch : eingabe) {
            ch = verschiebe_buchstaben_in_bereich(ch, ver, 'A', 'Z');
            ch = verschiebe_buchstaben_in_bereich(ch, ver, 'a', 'z');
            cout << ch;
        }
        cout << endl;
    }
    


  • @JK1805 Zeile 14 if (buch < 65 || buch>90 && buch < 97 || buch>122)macht nicht das, was du erwartest.
    Auch && und || haben eine Priorität wie * und +.
    (Danke wob)

    Mit if else könntest du dir die Zeile auch sparen.
    Es gibt nette Funktionen wie isalpha(), isupper(), islower()

    Und es gibt den Modulooperator % (rest einer Ganzzahldivision)
    Den kann man benutzen, wenn man einen Wertebereich als Ring haben möchte.

    PS. woher hast du den Begriff "if-Schleife"?



  • @DirkB sagte in Caesar Verschlüsselung:

    @JK1805 Zeile 14 if (buch < 65 || buch>90 && buch < 97 || buch>122)macht nicht das, was du erwartest.

    Doch. Sie testet, ob es ein nicht-Buchstabe ist. Dazu ist der Bereich vor A und der zwischen Z und a sowie der hinter z ausgeschlossen.



  • @wob Ja, wobei es komisch ist es so zu schreiben.
    Normalerweise schreibt man sowas als ((buch < 65 || buch > 90) && (buch < 97 || buch>122)). Das Ergebnis ist hier zufällig das selbe ohne die zusätzlichen Klammern, aber nur weil die Zahlen so schön sortiert sind. Was die Vermutung nahelegt dass der Verfasser dieser Zeile evtl. nicht weiss wie das mit den Prioritäten bei && und || funktioniert.



  • @hustbaer sagte in Caesar Verschlüsselung:

    Normalerweise schreibt man sowas als ((buch < 65 || buch > 90) && (buch < 97 || buch>122))

    Hm... ehrlich gesagt stimme ich dem nicht zu.
    Ich würde es eher so schreiben (also insbesondere würde ich den gültigen Bereich testen und dann ein ! rausziehen):

    bool isBuchstabe = (buch >= 'A' && buch <= 'Z' ) || (buch >= 'a' && buch <= 'z'));
    if (!isBuchstabe) { ... }
    

    Wobei isalpha ja schon genannt wurde.

    Und der Variablenname "buch" ist auch furchtbar. Hier geht ja nicht um ein Buch, sondern um irgendein Zeichen... (dieser Kommentar geht natürlich an @JK1805 und nicht an dich, @hustbaer)



  • @wob Ja, eh. Ich meine nur wenn man es schon ohne ! schreibt, dann mit Klammern. Mit ! kann man es auch ohne Klammern schreiben - wobei ich es nicht verkehrt finde die "überflüssigen" Klammern trotzdem zu schreiben. Weil's dann auch Leute lesen können die die Operator Precedence bei && und || nicht im Schlaf wissen. (Ich muss auch immer nachdenken und die Eselsbrücke mit "&& entspricht *, || entspricht +" zu Hilfe nehmen.)

    Und 👍 für benamste Variablen. Hardcore C Programmierer werden da zwar den Kopf gegen die Wand schlagen, aber ich hab lieber ein paar mehr Bezeichner die mir beim "schnell Code Lesen" helfen, als mehr Funktionalität pro Bildschirmseite, wo ich den Code dann aber mühsam entziffern muss.



  • @hustbaer sagte in Caesar Verschlüsselung:

    wobei ich es nicht verkehrt finde die "überflüssigen" Klammern trotzdem zu schreiben

    Mein Argument für die Klammern ist, dass man sonst Warnungen bekommt 😉

    Zum Beispiel:

    warning: '&&' within '||' [-Wlogical-op-parentheses]
    note: place parentheses around the '&&' expression to silence this warning
    

Anmelden zum Antworten