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:

ARRAY in SUB Global Deklarieren

 
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
Muecke
Gast





BeitragVerfasst am: 05.01.2014, 13:14    Titel: ARRAY in SUB Global Deklarieren Antworten mit Zitat

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 lächeln

jetzt habe ich den explode programmiert lächeln 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 traurig

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

BeitragVerfasst am: 05.01.2014, 13:31    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1279
Wohnort: Ruhrpott

BeitragVerfasst am: 05.01.2014, 14:56    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 05.01.2014, 15:30    Titel: Globale Variablen überflüssig Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1279
Wohnort: Ruhrpott

BeitragVerfasst am: 05.01.2014, 16:20    Titel: Antworten mit Zitat

@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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Elor



Anmeldungsdatum: 12.07.2013
Beiträge: 205
Wohnort: Konstanz

BeitragVerfasst am: 05.01.2014, 19:41    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4702
Wohnort: ~/

BeitragVerfasst am: 05.01.2014, 19:42    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Muecke
Gast





BeitragVerfasst am: 05.01.2014, 19:43    Titel: Antworten mit Zitat

@Sebastian: also das mit der richtigen Deklaration ist noch so eine Sache bei mir, ... traurig

ich kann deine Erklärung gut nachvollziehen, danke.

warum ich i als SHARED-Variable gemacht habe kann ich erklären lächeln war nicht dafür gedacht das ich Daten unteren den Unterprogrammen Tauschen kann sondern das ich i überall verwenden kann lächeln 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 traurig *peinlich* das man dies im QB so machen musste.

@grindstone: deinem Programmcode kann ich folgen lächeln *Heppy* macht Sinn wenn das schneller ist noch besser lächeln 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 traurig
Nach oben
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4702
Wohnort: ~/

BeitragVerfasst am: 05.01.2014, 19:49    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Muecke
Gast





BeitragVerfasst am: 05.01.2014, 19:57    Titel: Antworten mit Zitat

he he, ja das meine ich also dein Beispiel um das i in einer FOR Schleife zu deklarieren lächeln


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: ~/

BeitragVerfasst am: 05.01.2014, 20:05    Titel: Antworten mit Zitat

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. zwinkern

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. grinsen
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Muecke
Gast





BeitragVerfasst am: 05.01.2014, 20:13    Titel: Antworten mit Zitat

OK macht aus sin wenn die Fehlermeldung dazu kommt lächeln sorry. werde mich in Zukunft dran halten.

ok wenn ich es weglasse bekomme ich weniger Fehlermeldungen lächeln 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 lächeln

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 lächeln doch das ist scheinbar nicht richtig traurig
Nach oben
Muecke
Gast





BeitragVerfasst am: 05.01.2014, 20:55    Titel: Antworten mit Zitat

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 zwinkern
jetzt geht es lächeln 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 lächeln. wird ja nicht Leichter traurig


das ist noch der Neue Code der auch geht lächeln getestet auf einem iMac mit WIN 7 lächeln

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

BeitragVerfasst am: 05.01.2014, 21:06    Titel: Würde auch ohne SHARED gehen Antworten mit Zitat

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. zwinkern 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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Muecke
Gast





BeitragVerfasst am: 05.01.2014, 21:20    Titel: Antworten mit Zitat

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 lächeln das ich damit ich auf die Werte außerhalb der SUB zugreifen kann lächeln.

Das jetzt ist so wie ich es zu beginn mir machen wollte lächeln

denn ich kann nun zwei Strings mit Trennzeichen bearbeiten und dann in einer FOR Schleife mit einem PRINT Erbebnis1(1), Erbebnis2(1) ausgeben lassen lächeln 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 lächeln
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

BeitragVerfasst am: 05.01.2014, 21:30    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Muecke
Gast





BeitragVerfasst am: 05.01.2014, 21:35    Titel: Antworten mit Zitat

Ok, ich dachte das ich dann einfach ein Leeres Feld bzw nichts zurück bekomme traurig habe es gerade mal Probiert das Programm bricht ab traurig

da muss ich eine Abfrage noch einbauen bei der Ausgabe lächeln
danke für den Hinweis, das kann entscheidend sein später.
Nach oben
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1279
Wohnort: Ruhrpott

BeitragVerfasst am: 06.01.2014, 11:06    Titel: Antworten mit Zitat

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! zwinkern

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. happy
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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Muecke
Gast





BeitragVerfasst am: 06.01.2014, 13:28    Titel: Antworten mit Zitat

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 zwinkern 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 lächeln habe dir ein Muster noch mal als Code angehängt zum Testen.


grindstone hat Folgendes geschrieben:
Ich hoffe, du kannst mir noch einmal verzeihen! zwinkern

Hmm, das muss ich mir mal überlegen zwinkern
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

BeitragVerfasst am: 06.01.2014, 17:59    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
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