 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
Verfasst am: 19.02.2009, 00:55 Titel: Bug in InStrRev ?? |
|
|
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 |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 19.02.2009, 07:47 Titel: |
|
|
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 |
|
 |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
Verfasst am: 19.02.2009, 10:50 Titel: |
|
|
Ich weiß,
das Problem tritt nur bei längeren Suchstrings auf.
Mit
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 |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 19.02.2009, 13:52 Titel: |
|
|
???
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!  _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
Verfasst am: 19.02.2009, 17:29 Titel: |
|
|
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  _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 19.02.2009, 21:17 Titel: |
|
|
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  |
Na dann war volta hier doch schon ganz richtig
Volta ist ja praktisch unser FB-Assembler Guru hier  |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 20.02.2009, 23:39 Titel: |
|
|
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 |
|
 |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
Verfasst am: 21.02.2009, 00:18 Titel: |
|
|
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 |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 21.02.2009, 14:10 Titel: |
|
|
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 |
|
 |
|
|
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.
|
|