Letztes Zeichen aus String entfernen



  • Hallo,

    arbeite an einem eigenen C++-Spiel und habe nun eine eigene Namens-Eingabe-Funktion geschrieben. Klappt auch ganz gut, nur das mit der Löschtaste funzt noch nicht so wirklich.

    ...
    //Mit SFML wird die Backspace-Taste abgefragt
    case sf::Key::Back:
      str = str.substr (0, str.size()-1);
      break;
    ...
    

    Meine String-Variable "str" soll immer, wenn ich die Backspace-Taste drücke, um ein Zeichen verkürzt werden, so als würde man Zeichen für Zeichen löschen. Leider kann ich mit dem oben genannten Befehl immer nur 1x ein Zeichen löschen. Ich muss immer erst wieder ein Buchstabe eingeben, bevor ich wieder einen löschen kann.

    Wie kann man das richtig umsetzen?

    Danke schonmal für eure Hilfe! 🙂



  • Erstmal ist es vermutlich einfacher, wenn du das Zeichen per erase() direkt aus dem String löschst anstelle deiner Kopiererei. Ansonsten kann ich aus dem Fragment nicht erkennen, warum der Code nur einmal funktioniert - was sagt denn der Debugger?



  • Also hier mal der ganze zusammengehörige Code:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <SFML\Window.hpp>
    #include <SFML\Graphics.hpp>
    #include <SFML\Audio.hpp>
    #include <SFML\Graphics\SOIL\SOIL.h>
    using namespace std;
    
    int main (int argc, char* argv)
    {
            sf::Event event;   //mit SFML eine Event-Handler-Instanz erzeugen
            string str;        //Variable für Namenseingabe
    ...
    ...
    //SFML Event-Handler
    while (App.GetEvent(event))
    {
    	//Wenn Text eingegeben wird
            if (event.Type == sf::Event::TextEntered)
    	{
    		if (event.Text.Unicode < 128)
    		{
    			//Maximal nur 30 Zeichen für Namenseingabe!
                            if (static_cast<int>(str.length()) < 30)
    			{
    				//Eingegebener Buchstabe der Variable "str" hinzufügen
                                    str += static_cast<char>(event.Text.Unicode);
                                    //SFML-Eingabemaske "Name" bekommt als Textinhalt die Variable "str"
    				Name.SetText (str);
    			}
    		}
    	}
    
    	//Wenn Taste gedrückt
    	if (event.Type == sf::Event::KeyPressed)
    	{
    		//Key-Code der gedrückten Taste ermitteln
                    switch (event.Key.Code)
    		{
    			//Mit ESC beenden
    			case sf::Key::Escape:
    				return (2);
    				break;
    
    			//Mit Return Name bestätigen
    			case sf::Key::Return:
    			{					
    				//Datenstrom (Name speichern)
    				fstream f;
    				f.open ("data/petname.dat", ios::out);
    				f << str << endl;
    				f.close();
    				break;
    			}
    
    			//Mit Backspace löschen
    			case sf::Key::Back:
    				str = str.substr(0, str.size()-1);
    				break;
    		}			
    	}
    }
    ...
    ...
    }
    

    Hoffe, man kann etwas daraus erkennen 😉



  • str.erase(str.end() - 1);



  • Danke für die Hilfe, nur leider bleibt das Problem bestehen. Ich kann wieder immer nur 1 Buchstabe löschen. 😞



  • Malta schrieb:

    Danke für die Hilfe, nur leider bleibt das Problem bestehen. Ich kann wieder immer nur 1 Buchstabe löschen. 😞

    Das muss funktionieren. (Wobei deine Methode das auch müsste.)
    Der Fehler wird woanders liegen, biste mal mit nem Debugger durch? Ich vermute mal bei der Grafikausgabe.



  • So, habe es jetzt folgendermaßen gelöst:

    //Event-Handler
    while (App.GetEvent(event))
    {
    	//Wenn Text eingegeben wird
            if (event.Type == sf::Event::TextEntered)
        	{
            	//Alle Tasten außer "Backspace" (ASCII-Wert 8) erlauben
    		if (event.Text.Unicode < 8 || (event.Text.Unicode > 8 && event.Text.Unicode < 128))
    		{
    			//Maximal 30 Zeichen bei Namenseingabe!
    			if (static_cast<int>(str.length()) < 30)
    			{
    				//eingegebener Buchstabe der Variable "str" hinzufügen...
    				str += static_cast<char>(event.Text.Unicode);
    				//...und als Textinhalt der Namenseingabemaske definieren
    				Name.SetText (str);
    			}
    		}
    		//falls "Backspace" gedrückt...
    		else if (event.Text.Unicode == 8)
    		{
    			//...prüfe erstmal, ob Name nicht schon leer ist!
    			if (!static_cast<int>(str.length()) == 0)
    			{
    				//wenn nicht, dann lösche das letzte Zeichen des Strings "str"
    				str.erase(str.end() - 1);
    				Name.SetText (str);
    			}
    		}
                }
            }
        }
    
    	//Wenn Taste gedrückt
    	if (event.Type == sf::Event::KeyPressed)
    	{
    		switch (event.Key.Code)
    		{
    			//Mit ESC beenden
    			case sf::Key::Escape:
    				App.ShowMouseCursor(true);
    				return (2);
    				break;
    
    			//Mit Return bestätigen
    			case sf::Key::Return:
    			{					
    				//Datenstrom (Name speichern)
    				fstream f;
    				f.open ("data/petname.dat", ios::out);
    				f << str << endl;
    				f.close();
    				break;
    			}
    		}			
    	}
    }
    

    So klappt es jetzt. Es lag an den Unicode-Werten und das war bei meinem letzten Beispiel doppelt gemoppelt, da ich oben bereits mit "event.Text.Unicode < 128)" alle Tasten (inkl. Backspace) abgefragt habe und unten nochmal mit meinem Code, den ich anfangs gepostet habe.

    Danke nochmal für eure Hilfen! 🙂


Anmelden zum Antworten