String durchsuchen



  • Hi,

    hab ein Problem will ein Text nach bestimmten Inhalt durchsuchen, welches zwischen < > steht. Jedoch muss ich immer den Inhalt des String bis zu dem 1 Treffer löschen damit er mir den 2 Treffer anzeigt. Sonst zeigt er mir immer den 1 Treffer an und nicht die anderen 19.

    for (int i=0; i < 20; i++)
    {
    text.
    int pos1 = text.Pos("<");
    int pos2 = text.Pos(">");
    Memo3->Lines->Add(text.SubString(pos1,(pos2-pos1)));
    text.Delete(1,pos2);
    }
    

    Wie kann ich das machen, dass er mir alle 20 Treffer anzeigt ohne den Inhalt vor dem Fund in dem String zu löschen.

    Würde mich auf eine schnelle Antwort freuen.

    Gruß
    Sapzero

    ->Sorry hab ausversehen ins falsche Forum, sollte eigentlich ins C++ Builder. Bitte verschieben. 🙄



  • http://www.cplusplus.com/reference/string/string/

    Spezieller:
    http://www.cplusplus.com/reference/string/string/find/

    Edit: gilt nur für Standardstrings.
    Da du AnsiStrings verwendest, bist du wohl im C++Builder-Forum besser aufgehoben.



  • Nanyuki schrieb:

    http://www.cplusplus.com/reference/string/string/

    Spezieller:
    http://www.cplusplus.com/reference/string/string/find/

    Edit: gilt nur für Standardstrings.
    Da du AnsiStrings verwendest, bist du wohl im C++Builder-Forum besser aufgehoben.

    Ich hatte jetzt auf ein Beispiel gehofft. Das Hilft mir nicht viel weiter er erkennt bei mir .find net.



  • Was heißt "erkennt find nicht". Du kannst das natürlich nur auf Strings anweden. Wo liegt das genaue Problem??

    Ach ja: Ich schließe mich meinem Vorgägner and. Stell' die Frage mal im Borland Builder Forum, da Du ja auch Komponenten (Memo..) des Builders verwendetst.

    lg, freakC++



  • freakC++ schrieb:

    Was heißt "erkennt find nicht". Du kannst das natürlich nur auf Strings anweden. Wo liegt das genaue Problem??

    Ach ja: Ich schließe mich meinem Vorgägner and. Stell' die Frage mal im Borland Builder Forum, da Du ja auch Komponenten (Memo..) des Builders verwendetst.

    lg, freakC++

    Fehler: find ist kein Element von UnicodeString

    Ich hab schon gemerkt das im Falschen Bereich bin.



  • Ja, für AnsiStrings gibt es lediglich Pos, was aber leider nicht die Möglichkeit bietet, die Startposition mit anzugeben.
    Ob die VCL da etwas elegantes bereitstellt, weiss ich nicht, aber ich würde mir nicht lange den Kopf zerbrechen und eine Hilfsfunktion benutzen.

    String readSomething(String& str,int& pos)
    {
      int len=str.Length();
      while (pos<=len && str[pos]!='<')pos++;
      if (pos>len)throw int();
      int startPos=pos;
      while (pos<=len && str[pos]!='>')pos++;
      if (pos>len)throw int();
      return str.SubString(startPos+1,pos-startPos-1);
    }
    
    [...]
    
    int pos=1;
    for (int i=0; i < 20; i++)
         Memo3->Lines->Add(readSomething(text,pos));
    


  • String readSomething(String& str,int& pos)
    {
      int len=str.Length();
      while (pos<=len && str[pos]!='<')pos++;
      if (pos>len)throw int();
      int startPos=pos;
      while (pos<=len && str[pos]!='>')pos++;
      if (pos>len)throw int();
      return str.SubString(startPos+1,pos-startPos-1);
    }
    
    [...]
    
    int pos=1;
    for (int i=0; i < 20; i++)
         Memo3->Lines->Add(readSomething(text,pos));
    

    Also habe dein Beispiel ausprobiert und hat auch Funktioniert.
    Jedoch als ich nach einem Text gesucht habe der so Anfangen sollte "Auftrag1" und so enden sollte "=ok" hats nicht Funktioniert.

    Fehler der aufgetreten ist:
    Konvertierung von 'wchar_t' nach 'const char *' nicht möglich

    Was müsste ich ändern?



  • Dann musst du die Funktion so verändern, dass nicht nur ein einzelnes Zeichen verglichen wird, sondern ein ganzer String (z.B. mit strcmp oder einer ähnlichen Hilfsfunktion).
    Oder noch besser: du nimmst einfach deinen ersten Ansatz und verwendest aber std::string, damit kannst du nämlich find verwenden.

    So kommst du von AnsiString zu std::string (andersherum geht es genauso):

    std::string sText=text.c_str();
    


  • std::string sText=text.c_str();
    

    Es taucht immer der Fehler auf string ist kein Element von std.
    Wieso was muss ich machen um das zu beheben?

    Ich versuche auch das aber es geht nicht:
    UnicodeString name = "mustermann";
    UnicodeString a;
    std::string sa=a.c_str();
    sa = sprintf("Hallo %s wie geht es dir?",name");

    Fehler: string ist kein Element von std
    undefiniertes Symbol sa
    undefinierte Funktion sprintf



  • Der entsprechende Header muss noch eingebunden werden (#include <string>).



  • Nanyuki schrieb:

    Der entsprechende Header muss noch eingebunden werden (#include <string>).

    Funktioniert aber die Funktion sprintf wird nicht erkannt



  • Wozu brauchst du sprintf?
    Wenn du die Funktion unbedingt verwenden möchtest, musst du den passenden Header auch noch einbinden. Das dürfte cstdio sein.



  • Nanyuki schrieb:

    Wozu brauchst du sprintf?
    Wenn du die Funktion unbedingt verwenden möchtest, musst du den passenden Header auch noch einbinden. Das dürfte cstdio sein.

    Ich wollte mit der Funktion nur ein text ausgeben mit den zuvor eingegebenen Variablen.

    z.B.
    unicodestring a = "haus";
    sprintf ("Auftrag %s ..... =ok", a);

    Ist es möglich in sprintf Unicode String zu benutzen oder müsste ich auch die variable a in c-str umwandeln.



  • Mit C-Funktionen kenne ich mich nicht aus, erscheint mir in einem C++-Programm auch etwas fragwürdig.

    Wieso nicht so? Das entspricht deinem ersten Ansatz, nur jetzt mit std::string und find().

    std::string sText=text.c_str();
    size_t pos=0;
    for (int i=0;i<20;i++)
    {
      size_t spos=sText.find("<",pos);
      if (spos==std::string::npos)throw int();
      pos=sText.find(">",spos);
      if (pos==std::string::npos)throw int();
      Memo3->Lines->Add(String(sText.substr(spos+1,pos-spos-1).c_str()));
    }
    


  • Nanyuki schrieb:

    std::string sText=text.c_str();
    size_t pos=0;
    for (int i=0;i<20;i++)
    {
      size_t spos=sText.find("<",pos);
      if (spos==std::string::npos)throw int();
      pos=sText.find(">",spos);
      if (pos==std::string::npos)throw int();
      Memo3->Lines->Add(String(sText.substr(spos+1,pos-spos-1).c_str()));
    }
    

    Hi,
    habe dein Beispiel getestet, da kommt leider beim ausführen ein Fehler.
    Fehler: Im Projekt ist eine Exception der Klasse EAccessViolation mit der Meldung "Zugriffsverletzung bei adresse 7C80A2f0 in Modul'kernel32.dll'. Lesen von Adresse 7FF6001C" aufgetreten
    Es lässt sich Kompilieren jedoch nach dem Buttonclick taucht der Fehler auf.
    Woran könnte das liegen?



  • Versuch mit dem Debugger, die genaue Absturzstelle zu lokalisieren. Wenn du die umliegenden Variablen auf Korrektheit prüfst, solltest du den Fehler relativ schnell haben.



  • Sapzero schrieb:

    Hi,
    habe dein Beispiel getestet, da kommt leider beim ausführen ein Fehler.
    Fehler: Im Projekt ist eine Exception der Klasse EAccessViolation mit der Meldung "Zugriffsverletzung bei adresse 7C80A2f0 in Modul'kernel32.dll'. Lesen von Adresse 7FF6001C" aufgetreten
    Es lässt sich Kompilieren jedoch nach dem Buttonclick taucht der Fehler auf.
    Woran könnte das liegen?

    Was sagt denn der Debugger, d.h. in welcher Zeile tritt der Fehler auf?
    Mit welchem Text hast du das getestet und fängst du die int-Exceptions?



  • Was sagt denn der Debugger, d.h. in welcher Zeile tritt der Fehler auf?

    Der Fehler tritt schon in der ersten Zeile auf.
    Hier schon:

    std::string sText=text.c_str();
    

    Mit welchem Text hast du das getestet

    Ich hab nach einem Link gesucht in dem Text. Also nach www und de

    und fängst du die int-Exceptions?

    ka was das heist 😕



  • Wenn der Anfangsstring länger als 1 ist, muss das substr entsprechend noch angepasst werden.
    Außerdem sucht der Code in der Form nach genau 20 Paaren, wenn er keine mehr findet, wird ein int geworfen. Das musst du entweder fangen oder falls du höchstens 20 Paare finden willst, einfach durch break ersetzen.

    Dieser Code funktioniert bei mir problemlos:

    std::string sText=AsString(StdGetURL("http://www.c-plusplus.net/forum/viewtopic-var-t-is-252157-and-start-is-10.html"));
    std::string startToken="www.";
    std::string endToken=".de";
    size_t pos=0;
    for (int i=0;i<20;i++)
    {
      size_t spos=sText.find(startToken,pos);
      if (spos==std::string::npos)break;
      pos=sText.find(endToken,spos);
      if (pos==std::string::npos)break;
      if (pos-spos<50)cout << sText.substr(spos+startToken.length(),pos-spos-startToken.length()) << endl;
    }
    

    und gibt das aus:

    codezone
    assoc-amazon
    assoc-amazon
    c-plusplus.info, www.c-sar
    c-plusplus.net und www.baeckmann
    

    Von AnsiString nach std::string und wieder zurück macht bei mir im C++Builder auch keine Probleme.


Anmelden zum Antworten