Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Bug in InStrRev ??

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 19.02.2009, 00:55    Titel: Bug in InStrRev ?? Antworten mit Zitat

Entweder ich verstehe die Beschreibung der Funktion nicht richtig, oder FB übersieht das letzte Vorkommnis eines Strings:

Code:
dim StrData as string
dim SearchPat as string
declare function instrrev2(byref searchstr as string, byref searchpat as string) as integer

SearchPat = "TEST"

StrData = SearchPat+SearchPat+SearchPat+chr(0)

print InstrRev(StrData, SearchPat, -1)
print InstrRev2(StrData, SearchPat)
print mid(StrData, InstrRev2(StrData, SearchPat), len(SearchPat))

sleep


function instrrev2(byref searchstr as string, byref searchpat as string) as integer
    for q as integer = (len(searchstr) - len(searchpat) + 1) to 1 step -1
        if mid(searchstr,q,len(searchpat)) = searchpat then return q
    next
    return 0
end function


In dem String "TESTTESTTEST"+Chr(0) befindet sich ja an den Positionen 1, 5 und 9 der String "TEST". InstrRev findet den ersten an der Position 5. Wird da nicht einer vergessen?
_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 19.02.2009, 07:47    Titel: Antworten mit Zitat

Funzt einwandfrei.

Code:
Dim T as String = "TestTestTestTest" & Chr(0) 'Chr(0) ist übrigens nicht nötig bei einem String
Dim XPos as UInteger = Len(T)
Dim YPos as UInteger
For X as UInteger = 1 to Len(T)
   Print "Reverse search from: "; XPos
   YPos = InStrRev(T, "Tes", XPos)
   If YPos = 0 Then
      Print "No more found!"
      Exit For
   End If
   Print "Found at: "; YPos
   XPos = YPos - 1
Next
End 0


Code:
tpm@workboard-0:~/data/work/code/fb/test/test5$ ./test5
Reverse search from: 17
Found at: 13
Reverse search from: 12
Found at: 9
Reverse search from: 8
Found at: 5
Reverse search from: 4
Found at: 1
Reverse search from: 0
No more found!
tpm@workboard-0:~/data/work/code/fb/test/test5$



MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 19.02.2009, 10:50    Titel: Antworten mit Zitat

Ich weiß,

das Problem tritt nur bei längeren Suchstrings auf.

Mit
Code:
SearchPat = "TES"

funktioniert mein obiges Beispiel auch.

Wie lange die Suchstrings genau sein müssen, habe ich noch nicht herausgefunden, da die Schwelle bei der es dann nicht mehr funktioniert nicht immer die selbe ist.

Auf das Problem bin ich beim Durchsuchen eines Dateiinhalts nach einem bestimmten Muster gestoßen. Diese Datei endet nun zufällig mit einem Null-Char. Normalerweise schließe ich Strings natürlich nicht mit einem Null-Char ab, das macht ja FB automatisch.
_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 19.02.2009, 13:52    Titel: Antworten mit Zitat

??? missbilligen
Code:
Dim StrData As String
Dim SearchPat As String

SearchPat = "teste"

StrData = SearchPat + SearchPat + SearchPat
?StrData
Print InStrRev(StrData, "test")
StrData = StrData + "a"
?StrData
Print InStrRev(StrData, "test")
StrData = StrData + "a"
?StrData
Print InStrRev(StrData, "test")
Sleep

    testetesteteste
    0
    testetestetestea
    0
    testetestetesteaa
    11
nicht gut! Kopf schütteln
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 19.02.2009, 17:29    Titel: Antworten mit Zitat

Ja, ist mir auch schon aufgefallen. Die Funktion scheint öfters Probleme zu haben, und das ist nicht vom NULL-Char abhängig.

Ich bin kurzfristig in meinem Programm auf eine eigene InStrRev-Funktion umgestiegen. Diese funktioniert bis jetzt zuverlässig und hat nebenbei noch einen nützlichen Nebeneffekt: Sie ist schon bei kurzen Strings (ca. 10 Zeichen) mehr als doppelt so schnell und bei längeren Strings (100 000 Zeichen) ist sie mehr als 10 mal so schnell. Außerdem stürzt die eingebaute InStrRev-Funktion bei einer String-Größe von mehreren MegaBytes (mehrere 1 000 000 Zeichen) ab...

Für den Fall, dass meine Funktion jemanden interessieren sollte, poste ich sie hier:

Code:
function InStrRev3(byref searchstr as string, byref searchpat as string, byval startpos as uinteger = 0) as uinteger
    dim SStrPtr as integer = cint(strptr(searchstr))
    dim SPatPtr as integer = cint(strptr(searchpat))
    dim SStrLen as integer = len(searchstr)
    dim SPatLen as integer = len(searchpat)
    if startpos > 0 then SStrLen = startpos + SPatLen - 1
    if SStrLen > len(searchstr) then SStrLen = len(searchstr)
    if SPatLen > SStrLen then return 0
    asm
        std
        mov ecx, [SStrLen]
        mov ebx, [SPatLen]
        mov edi, [SStrPtr]
        mov esi, [SPatPtr]
        add edi, ecx
        sub edi, ebx
        mov al,  [esi]
      instrrev_continue: 
        repne scasb
        jz instrrev_foundfirst
        jcxz instrrev_notfound
      instrrev_foundfirst:
        push ecx
        push edi
        mov ecx, ebx
        add edi, ebx
        mov esi, [SPatPtr]
        add esi, ebx
        dec esi
        repe cmpsb
        jz instrrev_found
        pop edi
        pop ecx
        jmp instrrev_continue
      instrrev_found:
        pop edi
        pop ecx
        mov edx, edi
        sub edx, [SStrPtr]
        add edx, 2
        mov [Function], edx
      instrrev_notfound:
        cld
    end asm
end function


Ich bin mir sicher, man könnte den Code noch etwas optimieren (z.B. unnötige Speicherzugriffe)... aber in Assembler bin ich eher Anfänger als Profi. Vielleicht hat ja irgendein ASM-Freak Lust und Laune dazu lächeln
_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 19.02.2009, 21:17    Titel: Antworten mit Zitat

St_W hat Folgendes geschrieben:
aber in Assembler bin ich eher Anfänger als Profi. Vielleicht hat ja irgendein ASM-Freak Lust und Laune dazu lächeln


Na dann war volta hier doch schon ganz richtig lächeln
Volta ist ja praktisch unser FB-Assembler Guru hier lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 20.02.2009, 23:39    Titel: Antworten mit Zitat

Hi St_W,
teste die Funktion mal mit
Code:
Dim StrData As String
StrData = "testeatestetreste"
?StrData
Print InStrRev3(StrData, "test")
StrData = StrData+"a"
?StrData
Print InStrRev3(StrData, "test",5)
StrData = StrData+"a"
?StrData
Print InStrRev3(StrData, "test",3)
Sleep
bei den beiden letzten Aufrufen habe ich ein anderes Ergebnis erwartet?
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 21.02.2009, 00:18    Titel: Antworten mit Zitat

Welches Ergebnis denn? Ich denke es sollte so passen (ansonsten hab ich den Sinn des 3.Parameters falsch verstanden...).

Für mich bedeutet der 3.Parameter, dass im Bereich von diesem bis zum ersten Buchstaben der Suchstring beginnen muss. Falls du willst, dass der Suchstring komplett im Bereich enthalten sein soll, musst du nur die erste Zeile nach den DIM's in
Code:
    IF startpos > 0 THEN SStrLen = startpos - 1

ändern. Das Programm sucht dann von der StartPosition bis zur Position 1 nach dem Suchstring, der in diesem Bereich dann ganz enthalten sein muss.

Code:
 1 2 3 4 5 6 7 8 9
 a a a T E S T a a
InStrRev3(String, "TEST") gibt 4 zurück.


InStrRev3(String, "TEST", 5) schneidet den String ab:
 1 2 3 4 5 6 7
 a a a T E S T
und gibt ebenfalls 4 zurück.


InStrRev3(String, "TEST", 5) mit obiger Änderung würde mehr abschneiden:
 1 2 3 4 5
 a a a T E
und folglich 0 zurückgeben.


Ich hoffe, dass es sonst keine Fehler bei diesem Parameter gibt. Ich habe ihn nach dem schreiben der Grundfunktion noch schnell ergänzt, verwende ihn aber selbst in meinem Programm nicht.
_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 21.02.2009, 14:10    Titel: Antworten mit Zitat

Ok, ich habe das anders interpretiert,
"von der Startposition nach rechts das letzte Auftreten von TeilString suchen,
nur wenn keine Startposition übergeben wird oder diese = 0 ist, beginnt die Suche beim letzten Zeichen".
(Sonst würde Startposition=0 keinen Sinn machen!)

Was jetzt INSTRREV aus FB macht kann ich auch nicht feststellen??
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz