Satzzeichen aus einem String entfernen



  • Guten Tag zusammen.
    Ich habe hier eine kleine Übungsaufgabe in meinem C++ Buch bei welcher ich grade nichtmehr weiter komme ( es sind keine Hausaufgaben ich lerne das Freiwillig 😃 )
    Die Aufgabenstellung lautet :
    Schreiben sie ein Programm ,das die Satzzeichen aus einem String entfernt .Die Eingabe soll ein String mit Satzzeichen sein ,die Ausgabe ein String in dem die Satzzeichen fehlen .
    Hier mein bisheriger Lösungsansatz

    #include <iostream>
    #include <string>
    int main()
    
    {
      std::string Eingabe;
    
      std::cout << "Gib einen Satz mit Satzzechen ein \n";
      std::cin >> Eingabe ;
      for (std::string::size_type index = 0;index != Eingabe.size() ; index++)
      {
      if (ispunct (Eingabe[index])== true )
      {
    
      }
      }
    
      std::cin.get();
      return 0;
    }
    

    Das Problem ist nun ich kann zwar feststellen ob das jeweilige Zeichen welches grade kontroliiert wird ein Satzzeichen ist (das mache ich mit ispunct())aber wie kann ich dieses nun "löschen"?Ich habe mir überlegt es einfach mit einem Leeren String "" neu zu initialisieren allerdings würde das ein leerzeichen zur Folge haben ,und ich soll laut Aufgabenstellung ja nur das Zeichen entfernen und nichts neues hinzufügen ( wie ein Leerzeiche) wie lösche ich nun dieses einzelne Zeichen hat da jmd einen Tipp`?


  • Mod

    Mein Tipp ist ein Link auf eine Referenz und der Hinweis, dir solche Referenzen im Browser als Lesezeichen einzufügen:
    http://www.cplusplus.com/reference/string/string/
    hier noch eine:
    http://en.cppreference.com/w/cpp/string/basic_string

    Damit kommst du auf eine Idee, oder? Denk daran, wenn du ein Zeichen entfernst, dass das nächste Zeichen um eine Position vorrückt.

    Eine ganz andere Idee wäre, alle nicht-Satzzeichen in einen neuen String zu kopieren und dabei die Satzzeichen zu übergehen. Wie man hinten an einen String anfügt, findest du ebenfalls in den Referenzen.



  • Servus! Verwende die string-eigenen Funktionen (Stichwort string::find() und string::erase()).

    Edit: Rekursion wäre evtl. auch interessant, falls du damit vertraut bist.



  • Ich danke euch beiden ja das mit dem Kopieren der Nichtsatzzeichen in einen neuen String ist mir garnicht eingefallen super Idee von dir danke 🙂
    string::erase hab ich mir auch grad angeguckt das ist das was ich gesucht habe.
    Edit:
    Habe mich erst heute rangesetzt weiter dran zu arbeiten allerdings hat mein Programm noch einen Fehler

    #include <iostream>
    #include <string>
    int main()
    
    {
      std::string Eingabe;
    
      std::cout << "Gib einen Satz mit Satzzechen ein \n";
      std::cin >> Eingabe ;
      for ( std::string::size_type index = 0;index != Eingabe.size() ; index++)
      {
      if (ispunct (Eingabe[index])!= 0  )
    
    	 Eingabe.erase(index,1);
    
      }
      std::cout << Eingabe ;
      std::cin.get();
      return 0;
    }
    

    Denn wenn ich es Kompilliere und dann einen Satz mit Satzzeichen eingebe kommt eine Fehlermeldung es sei ein Fall für den Debugger .
    Nun habe ich einmal den Debugger rüber laufen lassen welcher mir folgendes Ausgibt :

    "Strings.exe": "C:\Windows\winsxs\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.6195_none_d09154e044272b9a\msvcp80.dll" geladen, Cannot find or open the PDB file
    "Strings.exe": "C:\Windows\SysWOW64\ole32.dll" geladen, Cannot find or open the PDB file
    "Strings.exe": "C:\Windows\SysWOW64\imm32.dll" geladen, Cannot find or open the PDB file
    "Strings.exe": "C:\Windows\SysWOW64\msctf.dll" geladen, Cannot find or open the PDB file
    Der Thread 'Win32-Thread' (0x17f8) hat mit Code -1073741510 (0xc000013a) geendet.
    Das Programm "[4692] Strings.exe: Systemeigen" wurde mit Code -1073741510 (0xc000013a) beendet.

    Habe nun auch nach der Meldung Cannot find or open the PDB file gesucht allerdings nichts hilfreiches gefunden .
    Mein Compiler ist der von Visual C++ 2010 ich bitte um Hilfe ,denn ich hab soweit ich das richtig sehe keinen Fehler in meinem Quelltext.

    Edit 2 : Jetzt wei´ich garnichtmehr weiter manchmal funktioniert es manchmal kommt eine Fehlermeldung ,und manchmal gebe ich einen String mit Satzzeichen und anderem ein ,es werden aber nicht alle sondern nur manche der . und , gelöscht sehr seltsam was ich da nun erschaffen habe 😃



  • Deine Indexzählung kommt aus dem Tritt wenn Du ein Zeichen löschst.
    Der Operator >> liest kein Whitespace(Leerzeichen u.dgl.), siehe getline().



  • Caligulaminus schrieb:

    Deine Indexzählung kommt aus dem Tritt wenn Du ein Zeichen löschst.
    Der Operator >> liest kein Whitespace(Leerzeichen u.dgl.), siehe getline().

    Achso natürlich 😃 mein Index kommt dadurch aus dem Tritt wie du so schön sagtest 😃
    Das wird auch der Grund sein weshalb es manchmal klappt manchmal nicht und manchmal nicht alles löscht ich werde es dann wohl so handhaben ,wie der erste nette Poster vorgeschlagen hat ( die Nichtsatzzeichen in einen neuen String kopieren ) danke für die netten/Hilfreichen ,und vor allem immer sehr schnellen Antworten von euch 👍



  • Naja, aus dem Tritt ...
    Stell Dir vor, Du findest an Stelle 5 ein Zeichen, und löschst dieses ...
    nun rückt das Zeichen von Stelle 6 an Stelle 5 vor.
    Du aber in Deiner Schleife zählst einfach weiter und untersuchst als nächstes Zeichen an Stelle 6.

    Damit übersiehst Du das Zeichen an Stelle 5, welches ja ursprünglich an Stelle 6 gewesen ist, und bevor es geprüft wurde, an Stelle 5 vorgerückt ist.

    Diese Problematik kannst Du umgehen, indem Du
    a) wie vorgeschlagen einen neuen String erstellst
    b) Deinen Weg beibehältst, aber den String von hinten nach vorne bearbeitest



  • Der Weg über die STL wäre das hier:

    std::string s = "igkn jni85eungbigukj3envruis<mfgjipu<njhwk<4uit8gr7u";
    
    s.erase(std::remove(std::begin(s), std::end(s), 'i'), std::end(s));
    

    Auch bekannt als Erase-Remove-Idiom und leicht anpassbar



  • Eher remove_if() .



  • Das meine ich mit leicht anpassbar.
    Denn so wird erstmal nur ein einzelnes Zeichen entfernt, will man mehrere weg haben, muss man das in einem Extra-Funktionsobjekt schreiben und dann remove_if nutzen.

    Zu der Klasse der Funktionsobjekte zähle ich jetzt Funktionen, Methoden, Funktoren und Lambda-Ausdrücke.


Anmelden zum Antworten