Buchempfehlung
Visual Basic 6 Kochbuch
Visual Basic 6 Kochbuch
Viele praktische Tipps zum Programmieren mit Visual Basic 6, die sich oft auch auf FB übertragen lassen. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Stringfunktionen

stringSplit

Lizenz:Erster Autor:Letzte Bearbeitung:
FBPSLMitgliedchutullu 02.12.2009

stringSplit Version 1.0

"Schon wieder ein Splitter" wird mancher denken. Aber weit gefehlt, die meisten Codes zum seperarieren
von Text sind dem Makel des redimmensionieren von Arrays behaftet. Aus diesem Grund kommt eine
einfach verkettete Liste zum Einsatz.

Aus performanten Gründen habe ich auf ein FIFO Prinzip verzichtet, somit ist das letzte Element der Liste
der erste Teilstring und im Umkehrschluss das erste Element der Liste das letzte Teilstück der zerlegten
Zeichenkette.

Weiterhin wird Byteweise gearbeitet also Zeichen für Zeichen, die Länge der Zeichenkette wird einmal
durchlaufen. Auf interne Prozeduren wie MID, INSTR usw. wurde der Geschwindigkeit wegen verzichtet.

Das bereitstellen des Speichers für ein neues Listenelement führte bei mir mit NEW und ALLOCATE zu un-
gewollten abstürzen, bei mir funktionierte nur CALLOCATE. Sollte es diesbezüglich Probleme geben wäre
ich über eine Info dankbar.

Die Zeile

char = This.toSplit[a-1]

kann bei Problemen durch

char = MID(This.toSplit,a,1)

ersetzt werden, wobei mir bis jetzt kein Probleme dies bezüglich bekannt geworden sind.

stringSplit - Version 2.00

Aus performanten Gründen und wegen der zahllosen Abstürze habe ich mich entschlossen den stringSplitter komplett neu zu gestalten. Der Code aus dieser Version ist wesentlich schlanker, verwirft das Listenkonzept komplett und, back to the roots, wird ein Array verwendet.

Die jetzige Version ist auf CSV Datenbanken abgestimmt. Die wesentlichste Veränderung ist die Beschränkung der einzelnen Teilstrings auf exakt 255 Zeichen. Ich denke das reicht für 99.999% aller Anwendungsfälle, alles andere würde aus meiner Sicht keinen Sinn machen, da die Laufzeit mit Länge der zu beschreibenden Datenbankzeile zunimmt.

Ansonsten : GPL / FBPSL - ready to use

Code - Version 1.0

'#######################################################################################################
/'
  (c) 2009 chutullu (chutullu2(at)yahoo(dot)de) / FreeBASIC-Portal.de
  
  stringSplit
  
  Version 1.2
  
  SplitList   Datentype
  
  SplitString Objekt
    * Zerteilt String in mit "sperator" getrennte Teile
    * Zerteilen erfolgt Byte-Weise  
    * einfache stackListe (filo)
    
    Struktur
      * toSplit   As String           - String welcher zerteilt werden soll
      * seperator As String           - Trenner
      * Split     As SplitList Ptr    - Liste
      * items     As Integer          - Anzeil der Strings in der Liste
      - spl (string2split, seperator) - zerteilt die Liste
      - addString (istring)           - fügt Element an die Liste an  
'/



Type SplitList
  item      As String
  nxt       As SplitList Ptr
End Type
Type splitString
  Version   As Double = 0.2
  toSplit   As String
  seperator As String * 1
  Split     As SplitList Ptr
  items     As Integer

  Declare Constructor ()
  Declare Sub  spl (ByVal string2split As String, ByVal seperator As String)
  Declare Sub  addString (ByVal istring As String)
End Type

Constructor splitString ()
  This.Split = 0
  This.items = 0
End Constructor

Sub splitString.spl (ByVal string2split As String, ByVal seperator As String)
  /'
    Aufruf    : obj.spl ("asdf,gadsfg,asfas",",")
    Ergebnis  : zerteilt übergebenen String in mit seperator getrennte Teile
    Variablen : a-Laufvariable; char-einzelnes Zeichen; dummy-Dummy-String
  '/

  Dim a     As Integer
  Dim char  As String * 1
  Dim dummy As String

  This.toSplit   = string2split
  This.seperator = seperator

  For a = 1 To Len(This.toSplit)          'solange bis ende der zeichenkette ereicht
    char = This.toSplit[a-1]                 '  zeichen = zeichnkette[a]
    If char = This.seperator Then         '  falls zeichen = seperator
        If Len (dummy) = 0 Then dummy = " "
        This.addString (dummy)              '    string an Liste hängen
        This.items += 1                     '    items zählen
        dummy = ""                          '    dummy = "" und weiter
    Else                                  '  falls nicht
        dummy += char                       '    zeichen zu dummy zählen
    EndIf
  Next
End Sub

Sub splitString.addString (ByVal istring As String)
  /'
    Aufruf    : obj.addString ("adsfa")
    Ergebnis  : fügt String vorn an die Liste an
    Variablen : istring-neuer String; this.Split-Liste
                dummy-neues Listenelement
  '/

  If This.Split = 0 Then                  'falls Liste leer
                                           '  liste anlegen
     This.Split       = Callocate (SizeOf ( SplitList ))
    This.Split->item = istring
    This.Split->nxt  = 0
  Else                                    'falls nicht
    Dim dummy As SplitList Ptr            '  neues Element erzeugen

    dummy       = Callocate (SizeOf ( SplitList ))
    dummy->item = istring
    dummy->nxt  = This.Split              '  Element nach vorn schieben


    This.Split  = dummy                   '  Anfang der Liste = neues Element

  EndIf

End Sub

Anwendung - Version 1.0

Ganz simples Zerteilen einer Zeichkette (Beispiel aus einer CSV-Datenbank). Natürlich habe ich die
Liste noch einmal "umgerubelt", so dass das letzte Listen-Element auch an erster Stelle im Array
steht.

An diesem Punkt bin ich natürlich an eleganten, performanten Lösungen interessiert.

'Anwendung

Dim splitting As splitString
Dim csvLine   As String = "52;27.12.2008;24;11;31;16;13;3;6;0;57.529.108,50;0;4.759.241,90;8;287.645,50;53;27.136,30;2036;1.836,60;6040;95,20;98986;29,00;138499;16,60;1592121;7,90"

splitting.spl(csvLine,";")

Dim array (1 To splitting.items) As String
Dim a                            As Integer

  a = 0
  While splitting.Split->nxt <> 0
     array(splitting.items-a) = splitting.Split->item
     splitting.Split=splitting.Split->nxt
     a+=1
  Wend
  array(1) = splitting.Split->item

  For a = 1 To UBound (array)
     Print a, array(a)
  Next

Sleep
End 0

Code - Version 2.0

Also möchte die zweite Version dem Leser nicht vorenthalten, es fehlen komplett alle Überprüfungen wie auf Nullstrings, Längenüberlauf (ct > 255) usw.

Type toExplode
  Const version = 2.02

  array  As String Ptr
  csv    As String
  lenght As UShort

  Declare Sub split (ByVal Istring As String, ByVal Isep As String)
End Type

Sub toExplode.split (ByVal Istring As String, ByVal Isep As String)
/'
  Ergebnis : Formatiert einen CSV String =>
             Beispiel        
             csv := "ab;abc;abcd" => csv := chr(2)+"ab"+chr(3)+"abc"+chr(4)+"abcd"
               Länge String 1         --------+     |     |     |      |      |
               String 1               --------------+     |     |      |      |
               Länge String 2         --------------------+     |      |      |
               String 2               --------------------------+      |      |
               Länge String 3         ---------------------------------+      |
               String 3               ----------------------------------------+
                                        
  Aufruf   : toExplode.split("ab;abc;abcd",";")
  Variable : a=Laufvar.; str_len=Länge des Strings;ct=Länge Teilstring&akteller Arrayeintrag
             items=Länge des Vektors; dummy=DummyString; Istring=Eingangsstring; Isep=Seperator
'/



  Dim a       As UShort  'Laufvariable
  Dim b       As UShort
  Dim str_len As UShort  'Länge des Strings
  Dim ct      As UShort  'Länge Teilstring
  Dim items   As UShort  'Anzahl der Arrayeinträge
  Dim dummy   As String = Istring 'dummy

  str_len  = Len(dummy)
  items Xor= items

  For a = 0 To str_len - 1
       b = str_len-a
      If Mid(dummy,b,1) = Isep Then
         Mid(dummy,b,1) = Chr(ct)
           ct          Xor= ct
           items         += 1
      Else
           ct            += 1
      EndIf
  Next a
  dummy       = Chr(ct) + dummy
  This.lenght = items + 1
  This.csv    = dummy

  This.array  = Callocate (SizeOf(String) * This.lenght)
  ct       Xor= ct


  For a = 0 To str_len - 1
     This.array[ct] = Mid(dummy,2+a,dummy[a])
     a += dummy[a]
     ct += 1
  Next a

End Sub

Anwendung - Version 2.0

Die Anwendung ist wesentlich "Anwenderfreundlicher", keine aufwendigen Listen, einfacher Code, schneller Zugriff :

Dim a     As Integer
Dim test  As toExplode
Dim csv   As String = "52;27.12.2008;24;11;31;14;13;3;6;0;57.529.108,50;0;4.759.241,90;8;287.645,50;53;27.136,30;2036;1.836,60;6040;95,20;98986;29,00;138499;16,60;1592121;7,90"
test.split(csv,";")

For a = 0 To test.lenght
    Print test.array[a]
Next

Sleep
End 0

Zusätzliche Informationen und Funktionen
  • Das Code-Beispiel wurde am 15.11.2009 von Mitgliedchutullu angelegt.
  • Die aktuellste Version wurde am 02.12.2009 von Mitgliedchutullu gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen