Problem mit string.find()



  • Also: mein Ziel ist es einfach alle "_" in einem String durch " " zu ersetzen. Das sieht bisher folgendermaßen aus:

    using namespace std;
    
    string STRING_CONVERT(string SHIFT_STRING)
    {
      /* Der zu bearbeitende String (SHIFT_STRING) wird dem Puffer (SHIFT_FREE)
         übegeben */
      string SHIFT_FREE = SHIFT_STRING;
    
      repeat:
    
      /* STRING_RESULT ist der Endwert, der unten auch per return übergeben wird.
         Ihm wird zunächst der Pufferwert übergeben */
      string STRING_RESULT = SHIFT_FREE;
    
      //Jetzt soll im Puffer nach "_" gesucht werden.
      int SHIFT_POS = SHIFT_FREE.find("_", 0);
    
      //"Wenn "_" gefunden wurde, soll nun durch " " ersetzt werden
      if(SHIFT_POS != 0)
      {
        SHIFT_FREE = SHIFT_FREE.replace(SHIFT_POS, 1, " ");
        /* Weil mehrere "_" auftauchen können und STRING_RESULT aktualisiert
           werden muss wird der Vorgang wiederholt */
        goto repeat;
      }
    
      return STRING_RESULT;
    };
    

    Bisheriges Ergebnis: Keine Compiler-Fehler. ABER das Programm "stürtzt ab".
    Wieso in Anführungszeichen? Naja ... für mich sieht das so aus als würde er eine Menge einfach überspringen. Nach nicht definiertem Verhalten sieht es weniger aus 😃 .

    2. Ich vermute, dass die if-Bedingung Probleme bereitet. Deshalb auch um auf den Topic zurück zu kommen: Welchen Ergebniswert liefert string.find() zurück wenn der Gesuchte Substring nicht gefunden wurde?

    3. Oder hab ich sonst irgendwas falsch gemacht?

    EDIT: sry ich habs jetzt selbst gelöst 🙂 man man quasi just in dem Moment als ichs poste 😃 sry nochmal.



  • Hi,

    1.) find() liefer bei nicht gefunden string::npos
    2.) meide goto und mach ne schöne Schleife 😉
    3.) die Funktion kann ein Einzeiler mit std::replace (alogrithm) sein 😉



  • Erstmal liefert find einen unsigned (size_t) Wert zurück. Dieser ist dann mit der Konstanten std::string::npos zu vergleichen. Ist der Rückgabewert gleich dieser Konstanten wurde der gesuchte String nicht gefunden.

    Außerdem solltest du das goto, durch eine while-Schleife ersetzen. 😉

    Greetz



  • Mach ich gerne aber im Moment habe ich ein ganz anderes Problem 😡

    Das ist der Code der die oben gezeigte Funktion (die jetzt wie gesagt funktioniert) verwendet:

    #include "convert.h"
    using namespace std;
    
    void practise(string DETECT_DATASET)
    {
      cout << "  Enter dr\x81 \bcken um neue Frage aufzurufen  " << endl;
      cout << endl;
    
      int TERMINATE_LOOP;
    
      while(TERMINATE_LOOP != 1)
      {
        ifstream QUESTION_FILE(DETECT_DATASET.c_str(), ios_base::out);
    
        if(!QUESTION_FILE)
        {
          cout << DETECT_DATASET << " konnte nicht geladen werden.  Die Datei fehlt/ ist besch\x84 \bdigt. " << endl;
    
          getch();
    
          return;
        }
    
        int QUESTION_NUMBER;
        int QUESTION_DATASET; 
        int QUESTION_LOOP;
    
        string STATE_NAME;
        string STATE_CITY;
        string USER_REPLY;
    
        QUESTION_FILE >> QUESTION_NUMBER;
    
        srand( (unsigned)time( NULL ) );
        QUESTION_DATASET = rand() % QUESTION_NUMBER + 1;
    
        QUESTION_LOOP = 2 * QUESTION_DATASET;
        while(QUESTION_LOOP >= 2)
        {
          QUESTION_FILE >> STATE_NAME >> STATE_CITY;
          QUESTION_LOOP -= 2;
        }
    
        STATE_NAME = STRING_CONVERT(STATE_NAME);
        STATE_CITY = STRING_CONVERT(STATE_CITY);
    
        cout << "  Wie hei\xE1 \bt die Hauptstadt von/der " << STATE_NAME << "?" << endl;
        cout << endl; 
        cout << "  Antwort:  ";
    
        cin  >> USER_REPLY;
    
        cout << endl; 
        cout << endl;
        cout << "  Die Antwort ist .... ";
    
        if (USER_REPLY == STATE_CITY)
        {
          cout << "  Richtig!  " << endl;
        }
        else if (USER_REPLY == "exit")
        {
          TERMINATE_LOOP = 1;
        }
        else
        {
          cout << "  Falsch!  " << endl;
          cout << endl;
          cout << "  Die richtige Antwort ist: " << STATE_CITY << endl;
        }
    
        getch();
    
        clrscr();
    
        QUESTION_FILE.close();
      }
    };
    

    Problem: Bei allen Strings die duch die Funktion verändert werden, gibt das Programm trotz richtiger Antwort "Falsch" aus. Woran kann das liegen? Also dort wo kein underscore entfernt wird geht's 😕 .

    Das sieht dann folgendermaßen aus:

    verändert: http://www.host2k.de/User/karpfenteich/bad.JPG
    nicht verändert: http://www.host2k.de/User/karpfenteich/good.JPG



  • cin >> liest nur bis zum ersten Leerzeichen ein.
    verwende:

    std::getline(std::cin, USER_REPLY);
    


  • Und warum nicht mit std::replace?

    void string_convert(std::string& string)
    {
        std::replace(string.begin(), string.end(), "_", "");
    }
    


  • 3.) die Funktion kann ein Einzeiler mit std::replace (alogrithm) sein 😉

    Man muss replace aber in einer Schleife aufrufen, oder?



  • ah es geht doch mit einem aufruf von std::replace in diesem fall. damit kann man aber nur einzelne buchstaben ersetzen. devils code ist falsch es muss '_', '' heissen.



  • ok vielen Dank ich probier's gleich mal aus 🙂

    EDIT: hmmm mein Compiler (Borland 5.5) sagt "undefined function" wenn er auf replace trifft. Muss ich da noch eine Headerdatei einbinden oder gehört die Funktion zu <string>?



  • #include <algorithm>
    
    ...
    
    std::replace(string.begin(), string.end(), '_', '')
    


  • OK es funktioniert jetzt soweit. Danke an alle die sich an der Lösung beteiligt haben.

    EDIT: Jetzt hab ich blöderweise doch noch ein Problem festgestellt 😃 . Wenn ich getline() einsetze findet im ersten Schleifendurchlauf keine Eingabe statt. Soll heißen die Eingabe wird beim ersten Mal übersprungen und wird erst im zweiten durchgang aktiv. Was kann man da machen?

    EDIT (die 2.) ^^: Ich bin jetzt selber noch auf die Funktion cin.ignore gestoßen aber ich wollte wissen ob es nicht doch noch eine Alternative gibt.


Anmelden zum Antworten