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:

Ich bin eingerostet... - Sub nimmt Deklarierte Variable nich

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



Anmeldungsdatum: 27.02.2006
Beiträge: 35

BeitragVerfasst am: 01.03.2006, 17:33    Titel: Ich bin eingerostet... - Sub nimmt Deklarierte Variable nich Antworten mit Zitat

So, neuer Thread, selbes Problem, alte Lösung, aber es geht nicht:

Ich lese in einem Programm mit line input einen Text in die auch schon deklarierte Variable cline$ ein.

Das Problem: Ich kann mein Programm nicht starten, da in der Sub die deklarierte Variable nicht akzeptiert wird traurig


Code:

DECLARE SUB check (cline$)
DIM SHARED cline AS STRING

'das öffnen und so lasse ich mal weg

LINE INPUT #1, cline$
Call check(cline$)


-----------------------------------------------
Sub check (cline$)

cline$ = UCASE$(cline$)

RETURN

END SUB




Was mache ich falsch ?
Die Variable cline$ soll mit ihrem Inhalt in der Sub weitergenutzt werden.
_________________
MfG JPT
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
otti



Anmeldungsdatum: 28.02.2005
Beiträge: 112
Wohnort: Wildberg

BeitragVerfasst am: 01.03.2006, 17:53    Titel: Antworten mit Zitat

Wie wärs damit:
Code:

DECLARE SUB check (subvariable$)
DIM SHARED cline AS STRING

...

LINE INPUT #1,cline$
check(cline$)

----
SUB CHECK (subvariable$)
subvariable$=UCASE$(subvariable$)
RETURN
END SUB



Achja:du weist schon das du mit deinem prog nur eine Zeile aus der Datei einliest?
So gings auch:

Code:

DIM SHARED zeile(100) AS STRING
DECLARE SUB check(nr%) AS STRING

...

WHILE NOT EOF(1)

i=i+1
LINE INPUT #1,zeile(i)
Check(i)

WEND

SUB check(nr%)

zeile(nr%)=UCASE$(zeile(i))
RETURN

END SUB



(Code nicht getestet!)

grüße otti
_________________
Gute Musik lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Tomtitom



Anmeldungsdatum: 20.09.2004
Beiträge: 308

BeitragVerfasst am: 01.03.2006, 17:57    Titel: Antworten mit Zitat

also entweder du schreibst
Code:
DIM SHARED cline AS STRING

und dann überall cline (ohne $)
oder du schreibst
Code:
DIM SHARED cline$

und überall cline$ (mit $)

achso, und dann bräuchtest du eigentlich auch gar keinen Parameter bei check. Da es aber mit Parametern besser ist, lass einfach
Code:
DIM SHARED cline AS STRING
weg.

Und was soll das RETURN eigentlich?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
JPT



Anmeldungsdatum: 27.02.2006
Beiträge: 35

BeitragVerfasst am: 01.03.2006, 18:19    Titel: Antworten mit Zitat

Nur so, ich habe natürlich eine Schleife drin, soll ja ein Converter werden.
Das Problem war nur, das die Sub ihren Dienst verweigert hat.

Das Return benötige ich, um, nachdem die sub check die Zeile von unnützen Zeichen bereinigt hat, weiter im Prog zu machen.
_________________
MfG JPT
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
JPT



Anmeldungsdatum: 27.02.2006
Beiträge: 35

BeitragVerfasst am: 01.03.2006, 18:24    Titel: Antworten mit Zitat

sry für dp, aber:

Irgendwie funktioniert trotzdem nichts, da die Sub ein und dieselbe Variable bearbeiten soll.


Ich muss noch einmal klarstellen, wofür ich das benötige, und wie ich es mir vorstelle:

Im Hauptprogramm wird innerhalb einer Schleife eine Zeile eingelesen. In eine Variable cline$. Dann wird eine Sub aufgerufen, die die Variable cline$ bearbeiten soll, und zurückgeben soll.

Frage: Wie realisiere ich diesen Ablauf ?
_________________
MfG JPT
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 01.03.2006, 21:04    Titel: Antworten mit Zitat

a) sub hat keine rückgabe und b) return hat in subs und functions unter qb glaub ich noch nix verloren

=>
Code:
declare function bla(blubb as string) as string

print blubb("hallo")

function bla(blubb as string) as string
    bla=UCASE$(blubb)
end function

_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
jb



Anmeldungsdatum: 14.01.2005
Beiträge: 2010

BeitragVerfasst am: 01.03.2006, 22:06    Titel: Antworten mit Zitat

Zum Thema SUBs und FUNCTIONs: Ein Link zur MonsterFAQ

jb
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Tomtitom



Anmeldungsdatum: 20.09.2004
Beiträge: 308

BeitragVerfasst am: 01.03.2006, 22:17    Titel: Antworten mit Zitat

@ JPT: Ok, hab dich erst falsch verstanden, du willst einen Call by reference
Dazu musst du entweder
Code:
Call check((cline$))
oder
Code:
check(cline$)
schreiben, das DIM SHARED ... kannst du weglassen. Und Das RETURN ist auch sinnlos.

Oder du machst es so wie MD, pass bloß auf, dass du nicht wie er die blas und blubbs vertauschst mit den Augen rollen

edit: bin irgendiwe immer etwas langsam verwundert
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
pinkpanther



Anmeldungsdatum: 28.05.2005
Beiträge: 79
Wohnort: Wien

BeitragVerfasst am: 02.03.2006, 00:32    Titel: Antworten mit Zitat

@MisterD
Damit die Verwirrung hier nicht überhand nimmt, mach ich mal deinen Code lauffähig. Abgesehen von der bereits erwähnten bla/blubb-Vertauschung ist es auch nicht möglich, den Funktionstyp als AS-Klausel zu formulieren.

Code:
DECLARE FUNCTION bla$ (blubb AS STRING)
PRINT bla$("hallo")

FUNCTION bla$ (blubb AS STRING)
 bla = UCASE$(blubb)
END FUNCTION


@Tomtitom
Zitat:
@ JPT: Ok, hab dich erst falsch verstanden, du willst einen Call by reference. Dazu musst du entweder
Call check((cline$))
oder
check(cline$)
schreiben...

Code:
Call check((cline$))

Das ist kein "Call By Reference", sondern ein "Call By Copy", bei dem eine Kopie des Parameters an die Prozedur übergeben wird. Änderungen, die innerhalb der Prozedur an dieser Kopie vorgenommen werden, wirken sich - im Gegensatz zum "Call By Reference" - nicht auf den Originalwert aus.

Code:
Call check(cline$)

Das hingegen ist ein "Call By Reference", bei dem die Adresse des Parameters an die Prozedur übergeben wird. In diesem Fall kann das Original des übergebenen Wertes von der Prozedur verändert werden.

@JPT
Bei deinem Code fällt mir zunächst auf, dass du eine SUB mit RETURN statt mit EXIT SUB/END SUB verlassen willst. RETURN ist nur nach einem mit GOSUB eingeleiteten Sprung zulässig. Ansonsten müsste cline$ innerhalb der SUB jedenfalls als Parameter (nicht als Variable!) "akzeptiert" werden (funktioniert bei mir einwandfrei).

Zur Unterscheidung:

Parameter und lokale dynamische Variable werden anders als statische Variable verspeichert und sind auch nur innerhalb der Prozedur zugänglich, in der sie vorkommen (QB erspart dir allerdings diese Unterscheidung, sodass du auf Parameter und lokale Variable innerhalb der jeweiligen Prozedur wie auf statische Variable zugreifen kannst).

Prozeduren sollten idealerweise kleine abgeschlossene Einheiten darstellen, die - abgesehen von der Parameterübergabe - keine Berührungspunkte mit den übrigen Prozeduren eines Programms haben. Auf globale Variable sollte - wo sinnvoll möglich - verzichtet werden, da sie, wahllos eingesetzt, ein Programm fehlerhaft und schwer verständlich machen können. Parameter und Variable sollten jedenfalls schon der Klarheit halber niemals den gleichen Namen teilen!

Parameter kannst du dir als "Durchreiche", also als Schnittstelle zwischen aufrufender und aufgerufener Prozedur vorstellen. Ein Prozeduraufruf wird intern in Adressen (Call By Reference) bzw. Werte (Call By Value bzw. By Copy) aufgelöst, und diese Werte werden der aufgerufenen Prozedur vorübergehend als Information zur Verfügung gestellt. Die aufgerufene Prozedur kann - technisch gesehen - diese Werte nicht verändern! Auch im Fall der Übergabe eines Parameters "By Reference" mit anschließender Änderung innerhalb der aufgerufenen Prozedur wird ja nicht die übergebene Adresse selbst verändert, sondern jener Wert, der an dieser Adresse verspeichert ist.

Jedenfalls ergibt sich aus dem "Durchreiche"-Prinzip der Vorteil, dass die aufrufende Prozedur nicht die Namensgebung der einzelnen Parameter der aufgerufenen Prozedur berücksichtigen muss, sondern nur Aufrufreihenfolge und Typ (Integer, String...). Andernfalls wären ja auch Programmbibliotheken (LIBs, QLBs) ohne Kenntnis des Quellcodes unbenutzbar.
_________________
lG
pinkpanther lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Tomtitom



Anmeldungsdatum: 20.09.2004
Beiträge: 308

BeitragVerfasst am: 02.03.2006, 10:59    Titel: Antworten mit Zitat

verdammt du hast recht, ich habs mal wieder voll verpeilt, meine Beispiele waren Call by Value, habs also genau vertauscht. Wenn man bei beiden Beispielen eine Klammer (rechts und links) wegnimmt, dann ist es Call by Reference.

Ich hoffe mal JPT blickt bei den ganzen Fehlern noch durch.
Aber dann verstehe ich auch nicht recht, warum das Programm von dir nicht klappen sollte, abgesehen von dem RETURN (und vielleicht noch das DIM zuviel) dürfte doch alles richtig sein. Vielleicht wäre es doch besser, wenn man mal das ganze Prog sieht.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
JPT



Anmeldungsdatum: 27.02.2006
Beiträge: 35

BeitragVerfasst am: 02.03.2006, 20:52    Titel: Antworten mit Zitat

Ihr wollt also den ganzen Code:

(Trotz der vielen Anmerkungen funktioniert es nicht *?*)

Code:

DECLARE SUB check (cline$)

DIM SHARED cline$

PRINT "This is the BZFlag World converter 1.0 -> 2.0"
PRINT
PRINT "Where is your world file located?"
INPUT "Please enter the complete path of the original file:", path$
INPUT "Please enter the path for the converted file:", path2$
CLOSE
OPEN path$ FOR INPUT AS #1
OPEN path2$ FOR OUTPUT AS #2

PRINT #2, "# This world has been converted with JPTs 1.0 -> 2.0 World Converter"
PRINT #2, "# Thanks for using this tool ! ;) "
PRINT #2, ""

DO UNTIL EOF(1)
 
  LINE INPUT #1, cline$

  CALL check(cline$)

  IF LEFT$(cline$, 1) = "#" THEN
    PRINT #2, cline$
  END IF
 
  IF LEFT$(cline$, 7) = "OPTIONS" THEN
    DO UNTIL cline$ = "END" OR EOF(1)
      PRINT #2, cline$
      LINE INPUT #1, cline$
      CALL check(cline$)
    LOOP
    PRINT #2, cline$
  END IF
 
  IF cline$ = "BOX" THEN
    LINE INPUT #1, cline$
  IF LEFT$(cline$, 4) = "name" THEN
    PRINT #2, "#" + cline$
  ELSE
    IF LEFT$(cline$, 3) = "pos" THEN
         
       'An dieser Stelle sollen aus einer Zeile 3 durch Leerzeichen getrennte Zahlen isoliert werden. Das kommt später.

     END IF
   END IF

  END IF
LOOP

CLOSE



SUB check (cline$)

cline$ = UCASE$(cline$)
DO
  IF cline$(chr) = "4" OR cline$(chr) = "9" OR cline$(chr) = "32" THEN
    cline$ = RIGHT$(cline$, 2)
  ELSE
    EXIT DO
  END IF
LOOP

END SUB



Wie gesagt, es soll eine Worldfile von einem Spiel eben convertieren.
Aber im Moment ist das Grundgerüst nicht lauffähig zwinkern

Innerhalb der Sub stoppt QB und sagt mir:
"Datenfeld nicht definiert"
_________________
MfG JPT
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Michael Frey



Anmeldungsdatum: 18.12.2004
Beiträge: 2577
Wohnort: Schweiz

BeitragVerfasst am: 02.03.2006, 21:04    Titel: Antworten mit Zitat

Hier ist der Fehler:
Code:
IF cline$(chr) = "4" OR cline$(chr) = "9" OR cline$(chr) = "32" THEN

und so sollte es gehen:
Code:
IF ASC(cline$) = 4 OR ASC(cline$) = 9 OR ASC(cline$) = 32 THEN

_________________
http://de.wikibooks.org/wiki/FreeBasic Jede Hilfe für dieses Buch ist Willkommen!
http://de.wikibooks.org/wiki/FreeBasic:_FAQ FAQ zu Freebasic (im Aufbau, hilfe Willkommen)
Neu mit Syntax Highlight
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
JPT



Anmeldungsdatum: 27.02.2006
Beiträge: 35

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

sry Michael, aber deine Version berücksichtigt nicht, das ASC nur ein Zeichen verarbeitet/en (kann)

Aber meine Version geht auch nicht: "Unzulässiger Funktionsaufruf"

Code:

If ASC(MID$(cline$, 1, 1)) = 4 OR ASC(MID$(cline$, 1, 1)) = 9 OR ASC(MID$(cline$, 1, 1)) = 32 THEN

_________________
MfG JPT
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
pinkpanther



Anmeldungsdatum: 28.05.2005
Beiträge: 79
Wohnort: Wien

BeitragVerfasst am: 02.03.2006, 23:32    Titel: Antworten mit Zitat

Beschreib uns doch bitte mal mit ein paar einfachen Worten, was genau die SUB check bewirken soll! Andernfalls können wir dir beim Suchen logischer Fehler nur schwer helfen.

Aufgrund deiner bisherigen Äußerungen rate ich mal munter drauflos, dass du dir die SUB check folgendermaßen vorgestellt haben könntest:
Code:
SUB check (cline$)
  cline$ = UCASE$(cline$)
  FOR i% = 1 TO LEN(cline$)
    SELECT CASE ASC(MID$(cline$, i%))
      CASE 4, 9, 32
        cline$ = RIGHT$(cline$, 2)
      CASE ELSE
        EXIT FOR
    END SELECT
  NEXT
END SUB

Stimmt's?

Der "unzulässige Funktionsaufruf" sollte damit Vergangenheit sein. Ob die Lösung deinen Programmzweck erfüllt, weiß ich aber nicht. Wenn du weitere Hilfe brauchst, mach bitte nähere Angaben zur Problemstellung.
_________________
lG
pinkpanther lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
JPT



Anmeldungsdatum: 27.02.2006
Beiträge: 35

BeitragVerfasst am: 03.03.2006, 09:01    Titel: Antworten mit Zitat

Ja, das stimmt.
Die Sub soll im Falle, das das erste Zeichen einen der drei Werte hat, das erste zeichen "rausnehmen"
_________________
MfG JPT
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Tomtitom



Anmeldungsdatum: 20.09.2004
Beiträge: 308

BeitragVerfasst am: 03.03.2006, 15:48    Titel: Antworten mit Zitat

hm, bist du sicher, dass die Version von Michael nicht funktioniert?
Denn ASC nimmt auch bei einen String immer das erste Zeichen, darum müsste das eigentlich klappen.

Und das
Code:
cline$ = RIGHT$(cline$, 2)
klappt auch nur, wenn cline$ genau 3 Zeichen lang ist. Besser wäre
Code:
cline$ = RIGHT$(cline$, LEN(cline$)-1)
(kann ja sein, dass du mal die Länge ändern willst)

Falls auch auch öfters z.B. CHR$(9) auftritt, dürfte auch der Code von Pink Panther nix bringen, da sich in der FOR-Schleife cline$ ändert und somit bei 2 hintereinanderfolgenden "Sonderzeichen" das 2. nicht erkennen würde.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
pinkpanther



Anmeldungsdatum: 28.05.2005
Beiträge: 79
Wohnort: Wien

BeitragVerfasst am: 03.03.2006, 20:10    Titel: Antworten mit Zitat

Wenn ich den Zweck der Prozedur richtig verstanden habe (siehe einleitenden Kommentar am Prozeduranfang), müsste die Lösung folgendermaßen aussehen:
Code:
SUB check (cLine$)
  'Zweck der Prozedur:
  '- wandelt die in der uebergebenen Zeichenfolge
  '  cLine$ enthaltenen Buchstaben in Grossbuchstaben um
  '- entfernt bestimmte Zeichencodes vom Beginn der
  '  uebergebenen Zeichenfolge cLine$, konkret die
  '  ASCII-Codes 4, 9 und 32.
  cLine$ = UCASE$(cLine$)
  DO WHILE LEN(cLine$)
    SELECT CASE ASC(cLine$)
      CASE 4, 9, 32
        cLine$ = MID$(cLine$, 2)
      CASE ELSE
        EXIT DO
    END SELECT
  LOOP
END SUB

Es werden hier nur die Codes 4, 9 und 32 entfernt, die am Anfang einer Zeichenfolge stehen. Wenn die Codes ein paar gültige Zeichen später abermals vorkommen, werden diese Zeichen dann nicht mehr entfernt. Will man auch das erreichen, muss man folgende, weniger effiziente Variante einsetzen:
Code:
SUB check (cLine$)
  'Zweck der Prozedur:
  '- wandelt die in der uebergebenen Zeichenfolge
  '  cLine$ enthaltenen Buchstaben in Grossbuchstaben um
  '- entfernt bestimmte Zeichencodes (konkret die ASCII-Codes
  '  4, 9 und 32), die an beliebiger Position der uebergebenen
  '  Zeichenfolge cLine$ vorkommen koennen.
  cLine$ = UCASE$(cLine$)
  tErgebnis$ = SPACE$(LEN(cLine$))
  FOR i% = 1 TO LEN(cLine$)
    tChar$ = MID$(cLine$, i%, 1)
    SELECT CASE ASC(tChar$)
      CASE 4, 9, 32
      CASE ELSE
        iAusgPos% = iAusgPos% + 1
        MID$(tErgebnis$, iAusgPos%) = tChar$
    END SELECT
  NEXT
  cLine$ = LEFT$(tErgebnis$, iAusgPos%)
END SUB


Beachte weiters:
UCASE$() ignoriert deutsche Sonderzeichen - UCASE$("ä") ergibt unverändert "ä"! Wenn deine Datei keine deutschen Sonderzeichen enthalten kann, kann dir dieses Verhalten natürlich egal sein.

Ich hoffe, dass dir damit geholfen ist!
_________________
lG
pinkpanther lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
JPT



Anmeldungsdatum: 27.02.2006
Beiträge: 35

BeitragVerfasst am: 03.03.2006, 23:13    Titel: Antworten mit Zitat

Es geht mir darum, nur die anfänglichen Tabs/Leerzeichen zu entfernen, um den Inhalt der Zeile gezielt zu Interpretieren.

Und die Select Case Variante funktioniert gut.
_________________
MfG JPT
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 04.03.2006, 01:16    Titel: Antworten mit Zitat

print ltrim$(" hallo")
...
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
pinkpanther



Anmeldungsdatum: 28.05.2005
Beiträge: 79
Wohnort: Wien

BeitragVerfasst am: 04.03.2006, 10:08    Titel: Antworten mit Zitat

@MisterD
LTRIM$() entfernt nur Leerzeichen, aber keine Tabstopps...
_________________
lG
pinkpanther lächeln
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 QBasic. 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