Elemente eines Strings in einer Variable speichern



  • Hallo Gemeinde,

    ich bin derzeit an einer Übungsaufgabe, deren Ziel es ist, eine Zahlenfolge in einer bestimmte Zeichenfolge zu verschlüsseln. Die zugehör. Zeichen definiere ich in dem Char Array "schluessel".

    Nun war meine Idee, den Eingabestring (welcher in Zahlen eingegeben wird) einzeln abzufragen und die Zahlen dann in das schluessel-Array einzusetzen:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    	// Variabeln
    	char schluessel[10] = {'L', 'A', 'D', 'E', 'N', 'T', 'I', 'S', 'C', 'H'};
    	string key_IN;
    	string key_neu;
    	short help;
    
    	// Auswahl
    	cout << "Ziffernfolge verschluesseln[1]" << endl;
    	cout << "Zeichenfolge entschluesseln [2]" << endl;
    	cout << "Exit [3]" << endl;
    	cin >> help;
    
    	system("CLS");
    
    	switch (help)
    	{
    		case 1:
    			cout << "Zu verschluesselnde Ziffernfolge eingeben: ";
    			cin >> key_IN;
    
    			int help1;
    
    			// Verschlüsselung
    			for (int i = 0; i < key_IN.size(); i++)
    			{
    				help = key_IN[i];
    
    				/*cout << schluessel[key_IN[i]];*/
    			}
    
    	}
    
    	system("Pause");
    }
    

    Nun habe ich aber folgendes Problem: Wenn ich help Abfrage bekomme ich z.b. für die Zahl 3 im String den Wert 51 raus?
    Das heißt, sobald ich versuche, ein Element des Strings in einer Variable zu schreiben, bekomme ich ganz andere Werte raus. Bei Zeichen wären es eben die ASCII Werte, aber ich geb ja schon Zahlen ein?

    Darf ich das überhaupt so machen? Irgendwie stehe ich ganz massiv auf dem Schlauch grad...

    Merci im Voraus,
    Ciao


  • Mod

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
      // Variabeln
      const char schluessel[] = "LADENTISCH";
    
      // Auswahl
      cout << "Ziffernfolge verschluesseln[1]" << endl;
      cout << "Zeichenfolge entschluesseln [2]" << endl;
      cout << "Exit [3]" << endl;
      char auswahl;
      cin >> auswahl;
    
      switch (auswahl)
        {
        case '1':
          cout << "Zu verschluesselnde Ziffernfolge eingeben: ";
    
          string zu_verschluesseln;
          cin >> zu_verschluesseln;
    
          // Verschlüsselung
          for (unsigned int i = 0; i < zu_verschluesseln.size(); ++i)
            {
              cout << schluessel[zu_verschluesseln[i] - '0'];
            }
          cout << endl;           
        }  
    }
    

    Gehe den Code Zeile für Zeile durch, schau dir an, was ich geändert habe und versuche zu verstehen, warum ich das gemacht habe.



  • Hey,

    erstmal Dankeschön für deine Hilfe! 🙂 So wie du es geschrieben hast funktioniert es, wie ich es mir eigentlich erhofft habe 🙂

    Also, ich fang mal an:

    Zuallererst fängt es mit der Übersichtlichkeit an. Die Variabelnnamen spiegeln nun auch wirklich das wider, was sie tun. 🙂
    Überdies hast du die Variabeln immer erst dann definiert, wenn sie tatsächlich gebraucht werden.

    Weiter:

    const char schluessel[] = "LADENTISCH";
    

    - Damit wird die Arraygroeße dynamisch je nach Textlänge angepasst. Da sich das im Laufe des Programms nicht mehr ändert, wird es als Konstante definiert.

    char auswahl;
    

    Du hast eine char Variable genommen, weil sie den halben Speicherbedarf einer short Variable einnimmt.

    for (unsigned int i = 0; i < zu_verschluesseln.size(); ++i)
    

    Statt i++ ++i.. hmm. Könnte mir vorstellen, dass damit zuerst i erhöht wird und dann geprüft wird, ob die Bedingung bereits erfüllt ist. So vermeidet man u.U. einen Leerdurchlauf?

    cout << schluessel[zu_verschluesseln[i] - '0'];
    

    Ah, das liegt daran, weil 0 ja den ASCII Wert 48 hat. Somit geht man durch das Subtrahieren von 0 wirklich vom Anfang der Tabelle aus. Drum waren meine Werte 48 zu hoch? 😉

    Gruß


  • Mod

    wolfbiker schrieb:

    Zuallererst fängt es mit der Übersichtlichkeit an. Die Variabelnnamen spiegeln nun auch wirklich das wider, was sie tun. 🙂
    Überdies hast du die Variabeln immer erst dann definiert, wenn sie tatsächlich gebraucht werden.

    Ja. 👍

    Weiter:

    const char schluessel[] = "LADENTISCH";
    

    - Damit wird die Arraygroeße dynamisch je nach Textlänge angepasst. Da sich das im Laufe des Programms nicht mehr ändert, wird es als Konstante definiert.

    Nicht ganz. Im Prinzip ist es nur Schreibfaulheit. Deines war genauso richtig, wenn nicht sogar besser, da veränderlich.

    char auswahl;
    

    Du hast eine char Variable genommen, weil sie den halben Speicherbedarf einer short Variable einnimmt.

    Nein. Speicherplatz hat damit gar nichts zu tun. Es verhindert aber ein unerwünschtes Verhalten, falls Buchstaben eingegeben werden, wo eine Zahl erwartet wird.

    for (unsigned int i = 0; i < zu_verschluesseln.size(); ++i)
    

    Statt i++ ++i.. hmm. Könnte mir vorstellen, dass damit zuerst i erhöht wird und dann geprüft wird, ob die Bedingung bereits erfüllt ist. So vermeidet man u.U. einen Leerdurchlauf?

    Das verhindert keine Leerdurchläufe, der Unterschied ist, wie aufwändig die Operation ++i gegenüber i++ ist. Versuch mal eine Funktion zu schreiben, die eine Variable um 1 erhöht und den neuen Wert zurück gibt (das ist ++i) und eine Funktion, die den alten Wert zurück gibt (das wäre i++). Du wirst feststellen, dass die zweite Variante komplexer ist. Bei einfachen Integern spielt dies zwar überhaupt keine Rolle, da für den Compiler einfach wegzuoptimieren, aber bei komplexen Datentypen kann das etwas ausmachen. Daher aus Konsistenzgründen imer ++i, wenn der Rückgabewert nicht mehr gebraucht wird.

    cout << schluessel[zu_verschluesseln[i] - '0'];
    

    Ah, das liegt daran, weil 0 ja den ASCII Wert 48 hat. Somit geht man durch das Subtrahieren von 0 wirklich vom Anfang der Tabelle aus. Drum waren meine Werte 48 zu hoch? 😉

    Genau. 👍



  • Hey,

    okay, nun ist mir fast alles klar. Mit dem ++i muss ich noch bisschen experimentieren um es vollständig zu verstehen, aber ich glaub, das bekomme ich hin!

    Also danke nochmal, jetzt kann es voller Motivation weitergehen 🙂

    Ciao


Anmelden zum Antworten