Return eines Strings und "Overflow" Error



  • Guten Tag,

    ich bin Anfänger in C++ und muss für die Uni eine Verschlüsselungsfunktion und eine Entschlüsselungsfunktion schreiben. Zur übung hab ich beide versucht auf eine andere weise zu programmieren, hier mein Code:

    #include <iostream>
    #include <string>
    
    char Verschluesselung(char Teststring[6], int j)
    {
    	char c;
    	char Lookup[2][27] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ","MNOPQRSTUVWXYZABCDEFGHIJKL"};
    	for(int i=0; i<=26; i++)
    	{
    	if(Teststring[j] == Lookup[0][i])
    	{
    		c = Lookup[1][i] ;
    	return c;
    	}
    	}
    	return 'X';
    }
    
    std::string Entschluesselung(char Code[6])
    		{
    	std::string Entschluesselt[6];
    	char Lookback[2][27] = {"MNOPQRSTUVWXYZABCDEFGHIJKL","ABCDEFGHIJKLMNOPQRSTUVWXYZ" } ;
    	for(int x=0; x<=5; x++) {
    	for(int i=0; i<=26; i++)
    		{
    		if(Code[x] == Lookback[0][i])
    			{
    			Entschluesselt[x]=Lookback[1][i];
    			}
    		}
    			return std::string(Entschluesselt);
    
    		}
    		}
    
    int main() {
    	std::string Teststring[6];
    	std::cin >> Teststring[6];
    	std::string Verschluesselt[6];
    	std::string Entschluesselt[6];
    
    	for (int j=0; j<=5; j++)
    	{
    	 Verschluesselt[j] = 'Verschluesselung(char Teststring[6],int j)';
    	}
    	std::cout << "Sie haben eingegeben: " << Teststring << std::endl;
    
    	std::cout << "Verschlüsselt ist das " << Verschluesselt << std::endl ;
    
    	std::cout << "Wiederum entschluesselt ist das " << Entschluesselung(char Code[6]) << std::endl;
    	return 0;
    
    }
    

    Nun spuckt mir Eclibse eine "Overflow" warnung bei Verschluesselt aus und das Programm reagiert nicht und lässt sich nicht ausführen.
    Bei Entschluessaelung kommt ein Error bei dem return (bin mir da nicht sicher hab noch nie nen string returned, den syntax hab ich mir ergoogelt) und deswegen will eclipse es nicht builden?

    Danke für jede Hilfe



  • Warum legst du Arrays von std::strings an?

    Die Texte der Fehler und Warnungen sagen, worum es geht. Warum zeigst du sie nicht?



  • Das

    'Verschluesselung(char Teststring[6],int j)'
    

    ist kein String. Einfache und doppelte Anführungszeichen haben unterschiedliche Bedeutung.



  • ähm du weißt, dass du ein array aus strings (zeile 39) anlegst und den kram dann auf irgendeine ungültige adresse einliest (zeile 40)?
    funktionsaufrufe setzt man soweit ich weiß auch nicht in '' (zeile 46).
    in zeile 48 und 50 gibst du auch wieder die adresse des arrays an und was du dir bei zeile 52 gedacht hast, weiß ich auch nicht.

    oder sind das irgendwelche mir unbekannten sonderfunktionen von c++?



  • Die gute alte ROT13-Verschlüsselung. ...bzw ROT12 in diesem Fall xD

    Ich habe deinen Code mal berichtigt:

    #include <iostream>
    #include <string>
    
    std::string Verschluesselung(std::string string)
    {
    	char Lookup[2][27] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ","MNOPQRSTUVWXYZABCDEFGHIJKL"};
    	for (int i=0; i < string.size(); i++) 	 // 'int i=0;' müsste korrekterweise: 'std::string::size_type i=0' sein
    	{
    		for(int j=0; j<26; j++)
    		{
    			if (string[i] == Lookup[0][j])
    			{
    				string.replace(i, 1, 1, Lookup[1][j]);	// ersetze ein Zeichen an Stelle i
    				break;									// nach ersetzen diese Schleife verlassen
    			}
    		}
    	}
    	return string;
    }
    
    std::string Entschluesselung(std::string string)
    {
    	char Lookup[2][27] = {"MNOPQRSTUVWXYZABCDEFGHIJKL","ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
    	for (int i=0; i < string.length(); i++)
    	{
    		for(int j=0; j<26; j++)
    		{
    			if (string[i] == Lookup[0][j])
    			{
    				string.replace(i, 1, 1, Lookup[1][j]);
    				break;
    			}
    		}
    	}
    	return string;
    }
    
    int main()
    {
    	std::string testString;
    	std::string verschluesselt;
    	std::string entschluesselt;
    
    	std::cin >> testString;
    	verschluesselt = Verschluesselung(testString);
    	entschluesselt = Entschluesselung(verschluesselt);
    
    	std::cout << "Sie haben eingegeben: " << testString << std::endl;
    	std::cout << "Verschlüsselt ist das " << verschluesselt << std::endl;
    	std::cout << "Wiederum entschluesselt ist das " << entschluesselt << std::endl;
    	return 0;
    }
    

    Vorne Weg: der berichtigte Code ist nicht sehr gut! Allerdings würde ein besserer Ansatz für dich zu verwirrend sein (Thema: std::vector oder Iteratoren).

    Dein Orginalcode war leider nicht ausführbar. Es waren einfach zu viele und zu schwerwiegende Fehler drin. Versuche bitte jede Zeile von deinem Code zu verstehen. Generell würde ich bei einem std::string nicht auf die Daten direkt zugreifen (z.B. via Teststring[6]). Es ist nicht das selbe wie ein char array. Als ich von C auf C++ gewechselt bin, hatte ich aber zugegebenermaßen ähnliche Probleme.

    Immer schön langsam Anfangen. Nimm dir Zeit, dann wird es schon 🙂

    viele Grüße,
    SBond



  • m_diff müsste die Verschiebung sein:

    // A = 65, Z = 90, a = 97, z = 122
    unsigned char CSimpleCryptDlg::EncryptChar( int ch )
    {
    	int ret, diff;
    	if( ch >= 97 && ch <= 122 )
    	{
    		ret = ch + m_diff;
    		if( ret < 97 )
    		{
    			diff = 97 - ret;
    			ret = 123 - diff;
    		}
    		else if( ret > 122 )
    		{
    			diff = ret - 123;
    			ret = 97 + diff;
    		}
    		return( static_cast<unsigned char> (ret) );
    	}
    	else if( ch >= 65 && ch <= 90 )
    	{
    		ret = ch + m_diff;
    		if( ret < 65 )
    		{
    			diff = 65 - ret;
    			ret = 91 - diff;
    		}
    		else if( ret > 90 )
    		{
    			diff = ret - 91;
    			ret = 65 + diff;
    		}
    		return( static_cast<unsigned char> (ret) );
    	}
    	else
    		return( static_cast<unsigned char> (ch) );
    

    }
    Ist eine älteres Spaßprogramm von mir, das alles von ROT1 bis ROT13 macht (mehr macht ja auch keinen Sinn).



  • EOP schrieb:

    Ist eine älteres Spaßprogramm von mir, ...

    Mit den Magic Numbers, globaler Variable und ohne cctype ist das unschön und führt Anfänger zu schlechtem Stil.



  • Rein aus Interesse, an welcher Uni studierst du? 😉



  • Danke für die Antworten!

    @Öcherjung deinem Namen nach zu urteilen weisst du an welcher 😃

    @manni66 So wurde das deklarieren von Strings bei uns eingeführt.
    Das mit den einzelnen und doppelten anführungszeichen ist mir bewusst, ich wollte mit der forschleife auch jede stelle von Verschluesselt einzeln mit nem char belegen

    @Hansklaus Zeile 40 soll dazu dienen das ich in der Konsole nen Test eingeben kann, der dann verschluesselt wird? Also das hat in anderen Programmen so schon funktioniert, deswegen weiss ich grad nicht was du meinst? 😕
    Dachte da nen char returned wird, dass ich den in die Anführungszeichen setzen muss, aber ergibt ja keinen Sinn, beim kopieren eines chars muss ich das ja auch nicht. Bedankt.
    Diese Funktionen mit std:: ... etc dienen dazu es an der Konsole auszugeben, das hat bisher eig in vorherigen Übungen funktioniert 😃

    @SBond Danke für die Mühe ! Da in der Aufgabenstellung steht, dass es nur ein 5 Stelliges Wort entschluesseln/verschluesseln sollen, hab ich den Kram mit string.size erstmal weggelassen, zu mal diese operationen noch nicht eingeführt wurden bei uns.
    Frage zu der Return anweisung bei Entschluesselung, er zeigt mir ne fehlermeldung an wenn ich es so wie geschrieben hast returnen will,
    ist "return std::string (Entschluesselt);" in ordnung? auch wenn ich nicht verstehe wieso ich das nochmal schreiben muss (typecast ist es ja auch nciht, sonst wäre ja das std::string in klammern oder?)
    Die Verschlusselungsfunktion wollte ich stellenweise mit der schleife arbeiten lassen. Die funktion hatte für einen buchstaben eig auch schon funtkioniert, bis ich sie umschreiben wollte für ein ganzes wort. Habe die anführungszeichen jetzt korrigiert, aber es will immernoch nicht laufen. es kommt der Fehler : Caesar.exe funktioniert nicht mehr. Das Programm wird aufgrund eines Problems nciht richtig ausgeführt. Das programm wird geschlossen und Sie werden benadchrichtrigt, wenn eine Lösung verfügbar ist.

    Hier Nochmal der Korrigierte Code

    #include <iostream>
    #include <string>
    
    char Verschluesselung(char Teststring[6], int j)
    {
    	char c;
    	char Lookup[2][27] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ","MNOPQRSTUVWXYZABCDEFGHIJKL"};
    	for(int i=0; i<=26; i++)
    	{
    	if(Teststring[j] == Lookup[0][i])
    	{
    		c = Lookup[1][i] ;
    	return c;
    	}
    	}
    	return 'X';
    }
    
    std::string Entschluesselung(std::string Code)
    		{
    	std::string Entschluesselt[6];
    	char Lookback[2][27] = {"MNOPQRSTUVWXYZABCDEFGHIJKL","ABCDEFGHIJKLMNOPQRSTUVWXYZ" } ;
    	for(int x=0; x<=5; x++) {
    	for(int i=0; i<=26; i++)
    		{
    		if(Code[x] == Lookback[0][i])
    			{
    			Entschluesselt[x]=Lookback[1][i];
    			break;
    			}
    		}
    		}
    	return std::string (Entschluesselt);
    		}
    
    int main() {
    	std::string Teststring[6];
    	std::cin >> Teststring[6];
    	std::string Verschluesselt[6];
    	std::string Entschluesselt;
    	for (int j=0; j<=5; j++)
    	{
    	 Verschluesselt[j] = Verschluesselung(char Teststring[6],int j);
    	}
    	std::cout << "Sie haben eingegeben: " << Teststring << std::endl;
    
    	std::cout << "Verschlüsselt ist das " << Verschluesselt << std::endl ;
    
    	std::cout << "Wiederum entschluesselt ist das " << Entschluesselt << std::endl ;
    	return 0;
    
    }
    


  • Ripleys schrieb:

    @Hansklaus Zeile 40 soll dazu dienen das ich in der Konsole nen Test eingeben kann, der dann verschluesselt wird? Also das hat in anderen Programmen so schon funktioniert, deswegen weiss ich grad nicht was du meinst? 😕

    das war mir schon klar. aber wenn du string str[6] deklarierst, kannst du die einzelnen strings mit str[0] ... str[5] ansprechen.
    str[6] gibt es nicht, das ist ungültiger speicherbereich. arrays laufen immer von 0 bis n-1.

    wenn du z.b. schreibst

    string string1[5];
    string string2[5];
    

    und du dann irgendwas in string1[5] schreibst, kann es passieren, dass du was in string2[0] schreibst, was - wenn du z.b. die software für ein atomkraftwerk schreibst - sehr böse enden kann.



  • Ripleys schrieb:

    @manni66 So wurde das deklarieren von Strings bei uns eingeführt.

    Nein, wurde es nicht.

    Ripleys schrieb:

    Das mit den einzelnen und doppelten anführungszeichen ist mir bewusst, ich wollte mit der forschleife auch jede stelle von Verschluesselt einzeln mit nem char belegen

    Soso

    Zusammenfassend: du hast nicht gelernt, daher nichts verstanden und versuchst jetzt mit diesem Nichtwissen ein Programm zusammnzuklöppeln. Dann fängst du am Besten mal von vorne an.



  • Huch, tatsächlich, [6] kommt ja nur bei dem deklarieren hinzu , mein fehler.
    Danke für den Hinweis! Da es immer noch nicht läuft wird das aber leider nicht der letzte Fehler gewesen sein .. 😃



  • dein korrigiertes programm ist ja auch genauso scheiße, wie das vorherige.

    also:

    //String erstellen
    string str;
    
    //Array aus Strings erstellen (hier 5 Stück), die von 0 - 4 angesprochen werden können
    string str[5];
    


  • HansKlaus schrieb:

    dein korrigiertes programm ist ja auch genauso scheiße, wie das vorherige.

    also:

    //String erstellen
    string str;
    
    //Array aus Strings erstellen (hier 5 Stück), die von 0 - 4 angesprochen werden können
    string str[5];
    

    ...schön dass du als cpp-Experte auf die Welt gekommen bist. (Wortwahl!)

    Aber mit den 'std::string Teststring[6]' liegt wirklich einiges in argen. So etwas habe ich so noch nicht gesehen und ich denke auch es ist ein Array of std::strings. Es ist also nicht vergleichbar mit einem 'char Teststring[6]'.

    @Ripleys: Soll lauf Aufgabenstellung ein std::string verwendet werden oder ein char-array? Oder steht da einfach nur, dass max. 6 Zeichen eingegeben werden sollen?

    viele Grüße,
    SBond



  • Da wir im Lande des allmächtigen C++ leben, ist std::string einem char-array vorziziehen. Reine Arrays statischer Größe werden recht selten gebraucht und sollten im Falle eines Falles durch std::array ersetzt werden, diese Klasse fängt nämlich gleich noch ungültige Indizes ab.



  • Es soll einfach ein Wort mit 5 Buchstaben angegeben werden.
    Das mit den Arrays tut mir leid, da hab ich wirklich nen Bock geschossen wohl..
    hab das soweit berichtigt, es läuft auch endlich, nur ich krieg egal bei welcher eingabe, die ausgabe:

    JOUFD
    Sie haben eingegeben: JOUFD
    Verschlüsselt ist das 0x61feec

    Es fehlt also die entschlüsselung und die Verschlüsselung ist auch nicht ganz richtig..

    #include <iostream>
    #include <string>
    
    char Verschluesselung(char Teststring[6], int j)
    {
    
    	char Lookup[2][27] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ","MNOPQRSTUVWXYZABCDEFGHIJKL"};
    	for(int i=0; i<=26; i++)
    	{
    	if(Teststring[j] == Lookup[0][i])
    	{
    		char c = Lookup[1][i] ;
    	return c;
    	}
    	}
    	return 'X';
    }
    
    std::string Entschluesselung(std::string Code)
    		{
    	char Entschluesselt[6];
    	char Lookback[2][27] = {"MNOPQRSTUVWXYZABCDEFGHIJKL","ABCDEFGHIJKLMNOPQRSTUVWXYZ" } ;
    	for(int x=0; x<=5; x++) {
    	for(int i=0; i<=26; i++)
    		{
    		if(Code[x] == Lookback[0][i])
    			{
    			Entschluesselt[x]=Lookback[1][i];
    			break;
    			}
    		}
    		}
    	return Entschluesselt;
    		}
    
    int main() {
    	char Teststring[6];
    	std::cin >> Teststring;
    	char Verschluesselt[6];
    	char Entschluesselt[6];
    	for (int j=0; j<=5; j++)
    	{
    	 Verschluesselt[j] = Verschluesselung(Teststring,j);
    	}
    	std::cout << "Sie haben eingegeben: " << Teststring << std::endl;
    
    	std::cout << "Verschlüsselt ist das " << Verschluesselt << std::endl ;
    	Entschluesselt= Entschluesselung(Verschluesselt);
    	std::cout << "Wiederum entschluesselt ist das " << Entschluesselt << std::endl ;
    	return 0;
    
    }
    


  • 6 Habe ich halt eingetragen wegen dem '\0' am ende des strings



  • #include <iostream>
    #include <string>
    
    char Verschluesselung(char Teststring[6], int j)
    {
    
    	char Lookup[2][27] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ","MNOPQRSTUVWXYZABCDEFGHIJKL"};
    	for(int i=0; i<=26; i++)
    	{
    		if(Teststring[j] == Lookup[0][i])
    		{
    			char c = Lookup[1][i] ;
    			return c;
    		}
    	}
    	return 'X';
    }
    
    std::string Entschluesselung(std::string Code)
    {
    	char Entschluesselt[6];
    	char Lookback[2][27] = {"MNOPQRSTUVWXYZABCDEFGHIJKL","ABCDEFGHIJKLMNOPQRSTUVWXYZ" } ;
    	for(int x=0; x<=5; x++) {
    		for(int i=0; i<=26; i++)
    		{
    			if(Code[x] == Lookback[0][i])
    			{
    				Entschluesselt[x]=Lookback[1][i];
    				break;
    			}
    		}
    	}
    	return Entschluesselt;
    }
    
    int main() {
    	char Teststring[6] = "ABCDE";
    	std::cin >> Teststring;
    	char Verschluesselt[6];
    	std::string Entschluesselt;		// --> std::string statt char
    	for (int j=0; j<=5; j++)
    	{
    		Verschluesselt[j] = Verschluesselung(Teststring,j);
    	}
    	std::cout << "Sie haben eingegeben: " << Teststring << std::endl;
    	std::cout << "Verschlüsselt ist das " << Verschluesselt << std::endl ;
    	Entschluesselt= Entschluesselung(Verschluesselt);  // Entschluesselung() gibt einen std::string zurück und kein char[]
    	std::cout << "Wiederum entschluesselt ist das " << Entschluesselt << std::endl ;
    	return 0;
    
    }
    

    Ausgabe:

    HALLO
    Sie haben eingegeben: HALLO
    Verschlüsselt ist das TMXXA
    Wiederum entschluesselt ist das HALLO
    

    So geht es.
    Allerdings gibt es bei diesem Code keine Sicherung bei der Eingabe. Wenn du mehr Zeichen eintippst, kommt es zum Überlauf.



  • Deshalb std::string benützen.



  • dub di dub.

    #include <cstddef>
    #include <cctype>
    #include <string>
    #include <iostream>
    
    std::string rotate( std::string const & str, std::size_t offset )
    {
    	std::string dst;
    
    	for( auto ch : str ) {
    		if( std::islower( ch ) )
    			dst += 'a' + ( ( ch - 'a' + offset ) % ( 'z' - 'a' + 1 ) );
    		else if( std::isupper( ch ) )
    			dst += 'A' + ( ( ch - 'A' + offset ) % ( 'Z' - 'A' + 1 ) );
    		else dst += ch;
    	}
    
    	return dst;
    }
    
    int main()
    {
    	std::string input;
    	std::cin >> input;
    
    	for( std::size_t i{}; i <= 'z' - 'a' + 1; ++i )
    		std::cout << rotate( input, i ) << '\n';
    
    	std::cout.put( '\n' );
    }
    

Log in to reply