 |
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 |
Muecke Gast
|
Verfasst am: 05.01.2014, 13:14 Titel: ARRAY in SUB Global Deklarieren |
|
|
Hallo miteinander,
ich bin dabei mir einen kleinen explode zu basteln, ja die gibt es schon jedoch ist das gut zum wider lernen und verstehen
jetzt habe ich den explode programmiert und es klappt auch.
ich kann einen String bei einem bestimmten Trennzeichen Trennen und in ein Arrey Speichern.
nachdem alles geht wollte ich es in einen SUB Packen um auf das Teil Öffter zugreifen zu können.
Das mit den Variablen / Arrey`s zu Deklarieren ist für mich noch etwas undurchsichtig
ich habe alle Variablen dazu gebracht das sie in Global gültig sind nur das Array bekomme ich nicht dazu , kann mir jemand sagen was ich Falsch mache?
Code: | DIM Shared As String explode_Array(1 To SeperatorAnzahl) ' Arrey in der Größe definiren |
Die ziele macht glaube ich die Probleme
Das ist mein Programm CODE
Code: | Dim Strg As String ' Hier ist der String drin
Dim Shared Separator As String ' Hier kommt das Trenzeichen rein
Dim Shared As Integer i
Dim Shared As Integer SeperatorAnzahl
DECLARE SUB explode (Separator As String, Strg As String, explode_Array() As String)
Strg = " Das, ist ein , ein, Test, mit, lauter, Separatoren "
Separator = ","
explode Separator, Strg, explode_Array()
Print "Das ist nicht in der SUB"
For i = 1 To UBOUND(explode_Array)
Print "'";explode_Array(i);"'"
Next
Sleep
Sub explode (Separator As String, Strg As String, explode_Array() As String)
Strg = LTrim(RTrim(Strg)) ' Leerzeichen am Anfang und Ende löschen
Dim As Integer Start = 1 ' Zählen wie viele Seperatoren im String vorkommen
For SeperatorAnzahl = 1 To Len(Strg)
Start = InStr(Start+1,Strg,Separator)
If Start = 0 Then Exit For
Next
DIM Shared As String explode_Array(1 To SeperatorAnzahl) ' Arrey in der Größe definiren
Do
i = i + 1
If instr(1,Strg,Separator)>0 Then
explode_Array(i) = LTrim(RTrim(Mid(Strg, 1, instr(1,Strg,Separator)-1)))' Ergebniss in Arrey Speichern (Leerzeichen am Anfang und Ende löschen)
Strg = LTrim(Mid(Strg, instr(1,Strg,Separator)+1, Len(Strg))) ' Ergebniss aus String Löschen
Else
explode_Array(i) = LTrim(RTrim(Mid(Strg, 1, instr(1,Strg,Separator)-1)))' Ergebniss in Arrey Speichern (Leerzeichen am Anfang und Ende löschen)
Exit Do ' Schleife abbrechen
EndIf
Loop
' Arrey ausgeben um zu schauen was wirklich drin ist
For i = 1 To UBOUND(explode_Array)
Print "'";explode_Array(i);"'"
Next
Print ""
Print "Das Arrey hat eine Maximal Groesse von";UBOUND(explode_Array);" Ebenen bekommen"
End Sub |
|
|
Nach oben |
|
 |
Muttonhead

Anmeldungsdatum: 26.08.2008 Beiträge: 565 Wohnort: Jüterbog
|
Verfasst am: 05.01.2014, 13:31 Titel: |
|
|
du könntest mit REDIM und SHARED dein Array global und dynamisch definieren.
dann brauchst du das Array garnicht erst der SUB übergeben
Code: | DECLARE SUB explode (Separator As String, Strg As String) |
innerhalb der SUB kannst du dieses Array dann wieder mit REDIM(diesesmal ohne SHARED) an die gewünschte Größe anpassen
Mutton |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1279 Wohnort: Ruhrpott
|
Verfasst am: 05.01.2014, 14:56 Titel: |
|
|
Hallo Muecke!
Das Parsen eines Strings geht wesentlich eleganter (und auch schneller) mithilfe von Pointern. Du setzt einen Pointer auf den Anfang des Teilstrings, einen zweiten auf dessen Ende und kopierst den so markierten Teilstring in dein Array.
Code: | ReDim Shared As String explode_Array(1) 'globales array
Declare Sub explode (Separator As String, Strg As String)
...
Sub explode (Separator As String, Strg As String)
Dim As Integer anfptr, endptr, x
x = 0
anfptr = 1 'pointer auf den anfang des strings setzen
Do 'string zerlegen
x += 1 'zähler erhöhen
ReDim Preserve explode_Array(x) 'array vergrößern
endptr = InStr(anfptr,Strg,Separator) 'endpointer auf nächsten separator setzen
explode_Array(x) = Mid(Strg,anfptr,endptr - anfgptr) 'teilstring in array schreiben
anfptr = endptr + Len(Separator) 'anfangspointer hinter den separator setzen (anfang des nächsten teilstrings oder stringende)
Loop While anfptr <= Len(Strg) 'weitermachen, bis der string zuende ist
End Sub | Das ist übersichtlicher, und der String bleibt erhalten, falls du ihn noch weiter bearbeiten möchtest.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 05.01.2014, 15:30 Titel: Globale Variablen überflüssig |
|
|
Hallo,
SHARED-Variablen sollten nur sehr sparsam verwendet werden z. B. für programmweite Einstellungen. Sonst schafft man sich Spaghetticode nicht durch Sprünge mit GOTO (Programmablauf), sondern durch die Datenflüsse im Programm.
Du kannst dir SUBs und FUNCTIONs (= Unterprogramme) vorstellen wie Maschinen oder Automaten. Oben füllst du irgendwas ein (z. B. in einen Trichter Plastikgranulat und in einen anderen Trichter Glitzerpulver). Dann wird die Maschine gestartet (ausgeführt) und unten kommt ein Output raus, zum Beispiel ein gepresster Plastikteller mit eingelagerten Glitzerpartikeln.
Die Maschine funktioniert nicht so, dass du zwar oben etwas einfüllst, aber noch 10 Meter davon entfernt einen weiteren Input in einen Schuhkarton legst, der sich dann magisch irgendwie in die Maschine überträgt, wovon man nichts sieht. Sondern die Maschine hat Einfüllstutzen, Trichter, Klappen ...., in die du die Inputs einbringst. So ist das bei Unterprogrammen auch. Sie erhalten Parameter, die sie verarbeiten. Und FUNCTIONs liefern davon dann einen Rückgabewert (Output) an den Aufrufer der Function zurück. SUBs hingegen verarbeiten nur irgendwas, liefern aber nichts zurück.
Das mit den Parametern ist hier schon ganz OK:
Code: | (Separator As String, Strg As String) |
Die beiden Variablen dürfen dann aber nicht auch noch mal zusätzlich als globale Variablen verwendet werden. Wozu auch? Die SUB erhält die Werte aus ihren beiden "Einfüllstutzen", die du hier definierst. Das ist die Schnittstelle des Unterprogramms, über das es vom Rest des Programms bedient wird. Die versteckten Tunnels im Untergrund, die SHARED-Variablen, sind da nicht nötig.
Optimal wäre es jetzt noch, wenn das Unterprogramm ihr Ergebnis, das Array, entweder als Datenstruktur direkt zurückliefern würde (als Ergebnis einer Function) oder wenn das Array auch als Parameter übergeben wird. Es gibt nämlich auch Parameter, in die das Unterprogramm etwas reintun kann, d. h. das ist keine Input-Einbahnstraße.
Wenn das Unterprogramm nur über seine Schnittstelle gekoppelt ist und nicht noch durch Mystery-SHARED-Datenflüsse, kannst du z. B. das Unterprogramm explode auch in einem anderen Programm verwenden (=> Wiederverwendbarkeit), ohne dass in diesem anderen Programm bestimmte globale Variabelen angelegt oder bearbeitet werden müssen. Auch reduziert man die Wechselwirkungen zwischen Programmteilen, wenn nicht mehrere Unterprogramme mit denselben globalen Wertablagen arbeiten. Das ist ja dann fast so unkomfortabel wie in ASM mit Registern zu hantieren, wo man den Registerwert erst auf den Stack legen muss, dann das Register selbst verwenden kann und zum Schluss den Ursprungswert wieder vom Stack ins Register zurückschreibt, damit nicht der Aufrufer oder so crasht.
Lange Rede, kurzer Sinn: Globale Variablen sind nur für Ausnahmefälle gedacht. Ein halbwegs vernünftig aufgebautes Programm kommt mit ganz wenigen oder sogar ohne aus.
Und: Einen Laufindex i als SHARED-Variable zu führen, ist wirklich unnötig und nicht gut.
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1279 Wohnort: Ruhrpott
|
Verfasst am: 05.01.2014, 16:20 Titel: |
|
|
@Sebastian
Nur mal aus Neugierde: Wie bekomme ich ein dynamisches Array als Rückgabewert einer Function?
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Elor
Anmeldungsdatum: 12.07.2013 Beiträge: 205 Wohnort: Konstanz
|
Verfasst am: 05.01.2014, 19:41 Titel: |
|
|
Zitat: |
Nur mal aus Neugierde: Wie bekomme ich ein dynamisches Array als Rückgabewert einer Function?
|
U.a. koennte eine Realisierung so aussehen:
Code: |
ReDim Shared DeinArray() As Integer
Function DeineFunktion(ByVal AnzahlElemente As Integer) As Any ptr
ReDim DeinArray(1 To AnzahlElemente)
DeineFunktion= @DeinArray(1)
End Function
' main
DeineFunktion(20)
For Index As Integer= 1 To 20
DeinArray(Index)= Index* 2
Next
For Index As Integer= 1 To 20
Print DeinArray(Index)
Next
GetKey ()
ReDim DeinArray(0) ' Braucht man das ueberhaupt ?
' end main
|
Vielleicht gibts auch noch andere moeglichkeiten, auf die schnelle ist mir aber nix anderes eingefallen. |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4702 Wohnort: ~/
|
Verfasst am: 05.01.2014, 19:42 Titel: |
|
|
grindstone hat Folgendes geschrieben: | @Sebastian
Nur mal aus Neugierde: Wie bekomme ich ein dynamisches Array als Rückgabewert einer Function? |
In FreeBASIC gar nicht. Aber du kannst es als Parameter übergeben; dieser ist bei Arrays ausschließlich BYREF möglich.
Oder eben über Pointer.
Zitat: | Das Parsen eines Strings geht wesentlich eleganter (und auch schneller) mithilfe von Pointern. |
Ich würde das sowieso über Stringindizierung machen statt über INSTR. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Zuletzt bearbeitet von nemored am 05.01.2014, 19:46, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
Muecke Gast
|
Verfasst am: 05.01.2014, 19:43 Titel: |
|
|
@Sebastian: also das mit der richtigen Deklaration ist noch so eine Sache bei mir, ...
ich kann deine Erklärung gut nachvollziehen, danke.
warum ich i als SHARED-Variable gemacht habe kann ich erklären war nicht dafür gedacht das ich Daten unteren den Unterprogrammen Tauschen kann sondern das ich i überall verwenden kann jedoch kann ich ja in einer For Schleife mir i deklarieren wenn ich das dann richtig verstanden habe ist das i auch nur innerhalb der For schleife Deklariert und nicht außerhalb der FOR schleife.
an das Thema Variablen Deklarieren kann ich mich auch so nicht merh wirklich erinnern *peinlich* das man dies im QB so machen musste.
@grindstone: deinem Programmcode kann ich folgen *Heppy* macht Sinn wenn das schneller ist noch besser was ich jedoch nicht verstehe ist wie du dort aus der "DO .. LOOP" raus kommt, denn das letzte zeichne muss kein Separator sein.
und ich habe auch hier wider das Problem das das Arrey nur in der SUB geht also nicht außerhalb Falsche Deklaration kommt als Antwort  |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4702 Wohnort: ~/
|
Verfasst am: 05.01.2014, 19:49 Titel: |
|
|
Für FOR-Schleifen bietet sich oft die direkte Initialisierung im Schleifenkopf an:
Code: | FOR i AS INTEGER = 1 TO 10
' ...
NEXT |
SHARED-Variablen haben hier den ganz klaren Nachteil, dass du, wenn die Schleife ein Unterprogramm aufruft, in dem dieselbe Variable verwendet wird, deinen Schleifendurchlauf schwer durcheinander wirbelst.
Zitat: | und ich habe auch hier wider das Problem das das Arrey nur in der SUB geht |
Das Array muss in diesem Beispiel im Hauptprogramm mit REDIM SHARED deklariert werden (so war das sicher auch gedacht). Ich würde allerdings lieber das Array im Hauptprogramm mit REDIM (ohne SHARED) deklarieren und als Parameter übergeben - dann kann es ebenfalls in der SUB mit REDIM PRESERVED verändert werden. Warum hier nicht SHARED? Weil du sonst ganz ausschließlich auf dieses Array angewiesen wärst und nicht zum Beispiel zwei getrennte String-Splits in zwei verschiedene Arrays durchführen könntest. D. h. deine SUB funktioniert nur für deinen einen speziellen Fall und ist schlecht wiederverwertbar. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
Muecke Gast
|
Verfasst am: 05.01.2014, 19:57 Titel: |
|
|
he he, ja das meine ich also dein Beispiel um das i in einer FOR Schleife zu deklarieren
ich probiere gerade das Arrey "explode_Array(x)" wider aus der SUB mit herauszugeben.
dazu habe ich mir die ByRef und BYVAL angeschaut doch ich habe da wohl was nihct richtig verstanden.
mit dem Befehl BYVAL habe ich die Variable als Einbandstraße in die SUB und mit ByRef ist der Weg in und aus der SUB.
doch ich bekomme immer eine Fehlermeldung mit der ich nicht wirklich was anfangen kann ;-(
das ist der CODE denn ich bei mir gerade mal mit ByRef gemacht habe:
Code: | ReDim Shared As String explode_Array(1) 'globales array
Declare Sub explode (Separator As String, Strg As String, ByRef explode_Array(x) AS String)
explode ",", "Hallo, Das, ist, ein, test , ."
For i As Integer = 1 To UBOUND(explode_Array)
Print "'";explode_Array(i);"'"
Next
Sub explode (Separator As String, Strg As String, ByRef explode_Array(x) AS String)
Dim As Integer anfptr, endptr, x
x = 0
anfptr = 1 'pointer auf den anfang des strings setzen
Do 'string zerlegen
x + = 1 'zähler erhöhen
ReDim Preserve explode_Array(x) 'array vergrößern
endptr = InStr(anfptr,Strg,Separator) 'endpointer auf nächsten separator setzen
explode_Array(x) = Mid(Strg,anfptr,endptr - anfgptr) 'teilstring in array schreiben
anfptr = endptr + Len(Separator) 'anfangspointer hinter den separator setzen (anfang des nächsten teilstrings oder stringende)
Loop While anfptr <= Len(Strg) 'weitermachen, bis der string zuende ist
End Sub |
|
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4702 Wohnort: ~/
|
Verfasst am: 05.01.2014, 20:05 Titel: |
|
|
Zitat: | doch ich bekomme immer eine Fehlermeldung mit der ich nicht wirklich was anfangen kann |
Andere vielleicht schon, deshalb immer die Fehlermeldung dazu posten, wenn andere helfen sollen.
Welche Fehlermeldung in diesem Beispiel kommt, ist mir jedoch klar: Arrays werden (wie oben erwähnt) immer BYREF übergeben, eine andere Übergabeart ist gar nicht möglich. Deswegen ist bei Arrays die Angabe von BYVAL oder BYREF nicht erlaubt. Also einfach weglassen.
Ach ja - wenn du es in die SUB als Parameter übergibst, braucht es nicht mehr SHARED zu sein.
edit: sind noch ein paar mehr Fehler drin, aber ich warte erst mal auf eventuelle Fragen, bevor ich ungefragt eine Lösung poste.  _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
Muecke Gast
|
Verfasst am: 05.01.2014, 20:13 Titel: |
|
|
OK macht aus sin wenn die Fehlermeldung dazu kommt sorry. werde mich in Zukunft dran halten.
ok wenn ich es weglasse bekomme ich weniger Fehlermeldungen das ist ein gutes Zeichen finde ich.
also wenn ich ein ARREY als Parameter in einer SUB habe dann kann ich auf das Arrey auch außerhalb der SUB zugreifen!
ich habe das X noch raus genommen beim Arrey
die Übrigen Fehlermeldungen sind die hier:
Zitat: | E:\FreeBASIC\FbEdit\..\fbc -s console "explode.bas"
explode.bas(5) error 57: Type mismatch, at parameter 3 of EXPLODE() in 'explode ",", "Hallo, Das, ist, ein, test , .", ""'
explode.bas(22) error 41: Variable not declared, anfgptr in 'explode_Array(x) = Mid(Strg,anfptr,endptr - anfgptr) 'teilstring in array schreiben'
Build error(s) |
und das ist der Aktuelle Code:
Code: | ReDim Shared As String explode_Array(1) 'globales array
Declare Sub explode (Separator As String, Strg As String, explode_Array() AS String)
explode ",", "Hallo, Das, ist, ein, test , .", ""
For i As Integer = 1 To UBOUND(explode_Array)
Print "'";explode_Array(i);"'"
Next
Sub explode (Separator As String, Strg As String,explode_Array() AS String)
Dim As Integer anfptr, endptr, x
x = 0
anfptr = 1 'pointer auf den anfang des strings setzen
Do 'string zerlegen
x + = 1 'zähler erhöhen
ReDim Preserve explode_Array(x) 'array vergrößern
endptr = InStr(anfptr,Strg,Separator) 'endpointer auf nächsten separator setzen
explode_Array(x) = Mid(Strg,anfptr,endptr - anfgptr) 'teilstring in array schreiben
anfptr = endptr + Len(Separator) 'anfangspointer hinter den separator setzen (anfang des nächsten teilstrings oder stringende)
Loop While anfptr <= Len(Strg) 'weitermachen, bis der string zuende ist
End Sub |
bei Aufruf der SUB muss ich ja dann auch das Parameter Arrey mit übergeben daher habe ich mal was leeres eingetragen doch das ist scheinbar nicht richtig  |
|
Nach oben |
|
 |
Muecke Gast
|
Verfasst am: 05.01.2014, 20:55 Titel: |
|
|
OK ich habe die Fehler gefunden ist das Peinlich gewesen.
Danke fürs bereit stellen des Codes.
das Arrey mus als Name und nicht als "" an die SUB Übergeben werden.
und beim Beenden der DO ... LOOP muss geprüft werden ob der EndZeiger 0 ist oder nicht wenn wenn 0 dann wider kein Trennzeichen mehr gefunden.
und dann habe ich noch einen Typfehler raus genommen
jetzt geht es bin ich Heppy.
Danke an alle.
irgend wie ist mir das echt Peinlich das ich wegen so Kleinigkeiten hier fragen musste, ich habe irgend wie schon Angst das Nächste zu machen . wird ja nicht Leichter
das ist noch der Neue Code der auch geht getestet auf einem iMac mit WIN 7
Code: | ReDim Shared As String explode_Array(1) 'globales array
Declare Sub explode (Separator As String, Strg As String, explode_Array() AS String)
explode ",", "Hallo, Das, ist, ein, test , .", explode_Array() ' Parameter in die SUB übergeben und das ARREY dann zurück bekommen
For i As Integer = 1 To UBOUND(explode_Array) ' Arrey auslesen und ausgeben
Print "'";explode_Array(i);"'"
Next
Sleep ' Damit der Monitor sich nicht gleich wieder Schlißt und mit tastendruck erst geschloßen wird.
Sub explode (Separator As String, Strg As String,explode_Array() AS String)
Dim As Integer anfptr, endptr, x ' Variablen definiren als Zahlen nur für die SUB sonst nirgens
x = 0
anfptr = 1 'pointer auf den anfang des strings setzen
Do 'string zerlegen
x + = 1 'zähler erhöhen
ReDim Preserve explode_Array(x) 'array vergrößern
endptr = InStr(anfptr,Strg,Separator) 'endpointer auf nächsten separator setzen
explode_Array(x) = LTrim(RTrim(Mid(Strg,anfptr,endptr - anfptr))) 'teilstring in array schreiben
anfptr = endptr + Len(Separator) 'anfangspointer hinter den separator setzen (anfang des nächsten teilstrings oder stringende)
Loop Until endptr <= 0 'weitermachen, bis der string zuende ist (wenn Seperator nict gefunden wierd wir 0 ausgegeben)
End Sub |
|
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 05.01.2014, 21:06 Titel: Würde auch ohne SHARED gehen |
|
|
Zitat: | das ist noch der Neue Code der auch geht |
Die Sache mit der globalen Variable ist aber immer noch nicht so sinnvoll gelöst. Wenn du dein Array (unschönerweise) als globale Variable im gesamten Programm verteilst, brauchst du es nicht als Parameter zu übergeben. Globale Variable plus Übergabe als Parameter hat keinen Sinn.
So würde jeder Aufrufer des Unterprogramms sein eigenes Ergebnis-Array bereithalten und an die SUB übergeben:
Code: | Declare Sub explode (Separator As String, Strg As String, explode_Array() AS String)
ReDim As String Ergebnis(1)
' ^--- ist nicht in *allen* Unterprogrammen sichtbar / aenderbar,
' sondern wird lediglich als Parameter uebergeben.
' String splitten!
' Parameter werden in die SUB uebergeben und das Ergebnis ins Array Ergebnis() geschrieben
explode ",", "Hallo, Das, ist, ein, test , .", Ergebnis()
' Array durchlaufen und ausgeben
For i As Integer = LBound(Ergebnis) To UBound(Ergebnis)
Print "'";Ergebnis(i);"'"
Next
Sleep ' Warten auf Tastendruck
End
' ======== Ende des Hauptprogramms ========
Sub explode (Separator As String, Strg As String, explode_Array() AS String)
' [...] kann aus deinem Posting kopiert werden.
End Sub |
Das heißt, wenn die SUB "B" die SUB explode aufruft, wird *nicht* das Ergebnis überschrieben, das vielleicht SUB "A" aus explode bekommen hat. Mehrere Aufrufer der Sub kämen sich nicht in die Quere, weil jeder Aufrufer sein eigenes Ergebnis-Array anliefert. Globale Variablen sind komplett vermieden. _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
Muecke Gast
|
Verfasst am: 05.01.2014, 21:20 Titel: |
|
|
Wow, das wird ja immer Besser,
ich muss also ein Arrey das in einer SUB Benutzt wird nicht Global machen und ich muss das auch nicht mit dem Selben Namen außerhalb der SUB verwenden. ich dachte das muss gleich sein das ich damit ich auf die Werte außerhalb der SUB zugreifen kann .
Das jetzt ist so wie ich es zu beginn mir machen wollte
denn ich kann nun zwei Strings mit Trennzeichen bearbeiten und dann in einer FOR Schleife mit einem PRINT Erbebnis1(1), Erbebnis2(1) ausgeben lassen das ist genial, Ihr seit die Größten für mich.
Tausend dank, und ich habe die Globale Variable nicht mehr das das Programm auch etwas schneller werden lässt da ich nicht immer alles mit übergeben muss an Daten"Müll".
DANKE.
Siht dann so aus
Code: |
Declare Sub explode (Separator As String, Strg As String, explode_Array() AS String)
ReDim As String Ergebnis1(1)
ReDim As String Ergebnis2(1)
explode ",", "Mama, Vater, Bruder, Schwester, usw.", Ergebnis1() ' Parameter in die SUB übergeben und das ARREY dann zurück bekommen
explode ",", "Mami, Papa , Dumpfb.., Bloe.. , ja ja", Ergebnis2() ' Parameter in die SUB übergeben und das ARREY dann zurück bekommen
For i As Integer = LBound(Ergebnis1) To UBound(Ergebnis1) ' Arrey auslesen und ausgeben
Print Ergebnis1(i),Ergebnis2(i)
Next
Sleep ' Warten auf Tastendruck
End
Sub explode (Separator As String, Strg As String, explode_Array() AS String)
Dim As Integer anfptr, endptr, x ' Variablen definiren als Zahlen nur für die SUB sonst nirgens
x = 0
anfptr = 1 'pointer auf den anfang des strings setzen
Do 'string zerlegen
x + = 1 'zähler erhöhen
ReDim Preserve explode_Array(x) 'array vergrößern
endptr = InStr(anfptr,Strg,Separator) 'endpointer auf nächsten separator setzen
explode_Array(x) = LTrim(RTrim(Mid(Strg,anfptr,endptr - anfptr))) 'teilstring in array schreiben
anfptr = endptr + Len(Separator) 'anfangspointer hinter den separator setzen (anfang des nächsten teilstrings oder stringende)
Loop Until endptr <= 0 'weitermachen, bis der string zuende ist (wenn Seperator nict gefunden wierd wir 0 ausgegeben)
End Sub |
|
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 05.01.2014, 21:30 Titel: |
|
|
Muecke hat Folgendes geschrieben: | Code: |
ReDim As String Ergebnis1(1)
ReDim As String Ergebnis2(1)
explode ",", "Mama, Vater, Bruder, Schwester, usw.", Ergebnis1() ' Parameter in die SUB übergeben und das ARREY dann zurück bekommen
explode ",", "Mami, Papa , Dumpfb.., Bloe.. , ja ja", Ergebnis2() ' Parameter in die SUB übergeben und das ARREY dann zurück bekommen
For i As Integer = LBound(Ergebnis1) To UBound(Ergebnis1) ' Arrey auslesen und ausgeben
Print Ergebnis1(i),Ergebnis2(i)
Next
|
|
In dem Code gibt es jetzt ein anderes Problem, nämlich beim Durchlaufen mit der FOR-Schleife. Die FOR-Schleife arbeitet ja auf den Grenzen des Arrays "Ergebnis1", d. h. von LBound(Ergebnis1) [=1. Index von Ergebnis1] bis UBound(Ergebnis1) [=letzter Index von Ergebnis1]. Trotzdem werden innerhalb der Schleife beide Arrays angesprochen.
Das funktioniert nur dann zufällig richtig, wenn beide Arrays gleich lang sind.
Wenn du z. B. "Hund,Katze,Maus" in Ergebnis1 splitten lässt und "Apfel,Birne,Kirsche,Erdbeere,Banane" in Ergebnis2, dann wirst du "Erdbeere" und "Banane" niemals sehen. Noch schlimmer wird's, wenn Ergebnis2 kürzer ist als Ergebnis1. Wenn Ergebnis1 10 Elemente hat, Ergebnis2 aber nur 5, greifst du ja auf nicht existierende Elemente zu (Ergebnis2(6) bis Ergebnis2(10)). Das führt dann nicht nur zum "Unterschlagen" von Array-Elementen, sondern zum Absturz des Programms.
Von daher müsstest du da nachbessern oder ggf. 2 Zählschleifen benutzen, um unterschiedlich lange Ergebnis-Arrays verarbeiten zu können. _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
Muecke Gast
|
Verfasst am: 05.01.2014, 21:35 Titel: |
|
|
Ok, ich dachte das ich dann einfach ein Leeres Feld bzw nichts zurück bekomme habe es gerade mal Probiert das Programm bricht ab
da muss ich eine Abfrage noch einbauen bei der Ausgabe
danke für den Hinweis, das kann entscheidend sein später. |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1279 Wohnort: Ruhrpott
|
Verfasst am: 06.01.2014, 11:06 Titel: |
|
|
Muecke hat Folgendes geschrieben: | was ich jedoch nicht verstehe ist wie du dort aus der "DO .. LOOP" raus kommt, denn das letzte zeichne muss kein Separator sein. | Da hast du recht, das habe ich tatsächlich übersehen.
In dem Programm, aus dem diese Sub stammt, ist es ihre Aufgabe, die -an einem Stück gesendete- Startmeldung einer Schachengine in einzelne Strings zu zerlegen und zur weiteren Verwendung in ein Array zu schreiben, wobei jeder Einzelstring und damit auch die gesamte Startmeldung mit einem Chr(13,10) abgeschlossen ist. Ohne Separator am Ende wird die Sub den letzten Teilstring nie zurückliefern, da der Endpointer dann eine 0 liefert.
Ich hoffe, du kannst mir noch einmal verzeihen!
Die einfachste Lösung dieses Problems ist es, vor der Zerlegung den Separator einfach an den String anzuhängen.
Code: | ReDim As String explode_Array(1)
Declare Sub explode (Separator As String, Strg As String, explode_Array() As String)
...
Sub explode (Separator As String, Strg As String, explode_Array() As String)
Dim As Integer begptr, endptr, x
x = 0
begptr = 1 'pointer auf den anfang des strings setzen
If Right(Strg,Len(Separator)) <> Separator Then 'sicherstellen, dass der string mit einem Separator abgeschlossen wird
Strg += Separator
EndIf
Do 'string zerlegen
x += 1 'zähler erhöhen
ReDim Preserve explode_Array(x) 'array vergrößern
endptr = InStr(begptr,Strg,Separator) 'endpointer auf nächsten separator setzen
explode_Array(x) = Mid(Strg,begptr,endptr - begptr) 'teilstring in array schreiben
begptr = endptr + Len(Separator) 'anfangspointer hinter den separator setzen
Loop While begptr <= Len(Strg) 'weitermachen, bis der string zuende ist
End Sub |
@nemored:
nemored hat Folgendes geschrieben: | Aber du kannst es als Parameter übergeben; dieser ist bei Arrays ausschließlich BYREF möglich. | Schon wieder etwas dazugelernt.
Zitat: | Ich würde das sowieso über Stringindizierung machen statt über INSTR. | Solange der Separator aus einem einzelnen Zeichen besteht, funktioniert das problemlos. Bei einem Separator mit variabler Länge wird die Sache schon komplizierter.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Muecke Gast
|
Verfasst am: 06.01.2014, 13:28 Titel: |
|
|
grindstone hat Folgendes geschrieben: | Muecke hat Folgendes geschrieben: | was ich jedoch nicht verstehe ist wie du dort aus der "DO .. LOOP" raus kommt, denn das letzte zeichne muss kein Separator sein. | Da hast du recht, das habe ich tatsächlich übersehen. |
kommt vor, nicht weiter schlimm das hat nur meinen Geist etwas gefordert und ich habe mir mehr damit beschäftigen müssen was glaube ich gerade ganz gut ist.
grindstone hat Folgendes geschrieben: | Ohne Separator am Ende wird die Sub den letzten Teilstring nie zurückliefern, da der Endpointer dann eine 0 liefert. |
da habe ich nicht drauf geachtet, daher habe ich es gerade noch mal getestet, als bei mir kommt die Letzte Zelle immer mit raus habe dir ein Muster noch mal als Code angehängt zum Testen.
grindstone hat Folgendes geschrieben: | Ich hoffe, du kannst mir noch einmal verzeihen! |
Hmm, das muss ich mir mal überlegen
Du weist ja, ich bin hier um was zu lernen auch wenn manche Dinge ich leichter in Erinnerung hatte irgend wie.
ich bin für jede Hilfe immer sehr dankbar.
Test CODE
Code: | Declare Sub explode (Separator As String, Strg As String, explode_Array() AS String)
ReDim As String Ergebnis1(1)
ReDim As String Ergebnis2(1)
explode "---", "1.Mama --- 2.Vater--- 3.Bruder---4.Schwester --- 5.usw.", Ergebnis1() ' Parameter in die SUB übergeben und das ARREY dann zurück bekommen
explode "--", "1.Banane-- 2.Birne-- 3.Apfel-- 4.Baum -- 5.Blume-- 6.Rassen", Ergebnis2() ' Parameter in die SUB übergeben und das ARREY dann zurück bekommen
Print "Wir sind nicht in der SUB: Ergebnis_1"
For i As Integer = LBound(Ergebnis1) To UBound(Ergebnis1) ' Arrey auslesen und ausgeben
Print Ergebnis1(i)
Next
Print
Print "Wir sind nicht in der SUB: Ergebnis_2"
For i As Integer = LBound(Ergebnis2) To UBound(Ergebnis2) ' Arrey auslesen und ausgeben
Print Ergebnis2(i)
Next
Print: Print "beliebige taste zum beenden": Sleep ' Warten auf Tastendruck
End
Sub explode (Separator As String, Strg As String, explode_Array() AS String)
Dim As Integer anfptr, endptr, x ' Variablen definiren als Zahlen nur für die SUB sonst nirgens
x = 0
anfptr = 1 'pointer auf den anfang des strings setzen
Do 'string zerlegen
x + = 1 'zähler erhöhen
ReDim Preserve explode_Array(x) 'array vergrößern
endptr = InStr(anfptr,Strg,Separator) 'endpointer auf nächsten separator setzen
explode_Array(x) = LTrim(RTrim(Mid(Strg,anfptr,endptr - anfptr))) 'teilstring in array schreiben
anfptr = endptr + Len(Separator) 'anfangspointer hinter den separator setzen (anfang des nächsten teilstrings oder stringende)
Loop Until endptr <= 0 'weitermachen, bis der string zuende ist (wenn Seperator nict gefunden wierd wir 0 ausgegeben)
End Sub |
|
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1279 Wohnort: Ruhrpott
|
Verfasst am: 06.01.2014, 17:59 Titel: |
|
|
Nur ein kleines Detail: Du brauchst den Endpointer nur auf "= 0" zu testen, nicht auf "<= 0", da Instr niemals einen negativen Wert liefert.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
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.
|
|