|
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 |
Raphael
Anmeldungsdatum: 17.03.2008 Beiträge: 18 Wohnort: Saarbrücken
|
Verfasst am: 04.04.2010, 14:36 Titel: Problem mit TYPE und DIM |
|
|
Einen schönen Ostersonntag in die Runde!
Ich habe ein Problem mit Arrays. Die brauche ich für ISAM, allerdings sollen die Arrays und Records nur so dimensioniert werden, wie sie gerade gebraucht werden. Der Anwender gibt zu Beginn des Programms die gewünschte Programmfunktion (1-11) ein. Jede Funktion soll einen unterschiedlichen Record mit unterschiedlichen Feldern dimensionieren.
Leider ist es dem Compiler (PDS 7.1) ziemlich egal, ob diese TYPE-Blöcke innerhalb einer SELECT CASE-Aufteilung stehen oder nicht. Beim dritten Block kommt immer "Out of memory", obwohl er das Record ja nur dann kreiren soll, wenn der Anwender das auch ausgewählt hat.
Mit anderen Worten: bei Auswahl 1 soll Block 1 ausgeführt werden, bei Auswahl 2 Block 2 usw. Der Compiler versucht aber immer, alle TYPE-Blöcke auszuführen und stößt da natürlich an spreichermäßige Grenzen. Es wäre aber ein Ding der Unmöglichkeit und eine gnadenlose Speicherplatzverschwendung, zu versuchen, immer alle Felder zu dimensionieren.
Sämtliche Versuche mit IF...THEN, GOSUB und ähnlichen Abfragen sind gescheitert.
Jemand eine Idee, was man da machen kann?
Zuletzt bearbeitet von Raphael am 04.04.2010, 15:25, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 04.04.2010, 15:15 Titel: |
|
|
Hallo,
ich werfe mal die vielleicht etwas ketzerische Frage in den Raum: Nutzt du QBX/PDS und ISAM aus bestimmten Gründen oder "nur so"?
Sonst würde ich nämlich ein FreeBASIC-Programm mit einer richtigen SQL-Datenbank im Hintergrund (heute absolut Standard) für praktischer halten. DBS wie MySQL, PostgreSQL, SQLite und Co. stehen alle kostenfrei zur Verfügung und sind viel leistungsfähiger und meiner Meinung nach viel komfortabler.
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
Raphael
Anmeldungsdatum: 17.03.2008 Beiträge: 18 Wohnort: Saarbrücken
|
Verfasst am: 04.04.2010, 15:24 Titel: |
|
|
Ich würde schon gerne bei QBX/PDS bleiben. An dem Programm arbeite ich seit 10 Jahren, bisher immer mit selbstgeschriebenen Datenbanken. Nun habe ich seit einem Jahr PDS und mich nach langem Zögern an ISAM herangewagt. Es scheint für meine Zwecke auch geeignet zu sein, nur setzt es eben dieses TYPE/DIM-Zeug voraus, und damit hatte ich bislang noch nie zu tun. Die gängige Literatur behandelt solche Spezialfälle natürlich nicht, aber es muß ja irgendeine Möglichkeit geben, daß nur diejenigen TYPE-Records im Speicher angelegt werden, die auch gebraucht werden. |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 04.04.2010, 15:29 Titel: |
|
|
ohne dass ich jetzt grade genau weiß was du tun willst, aber versteh ich das richtig dass du unter ein und dem selben variablennamen verschiedene type-arrays speichern willst abhängig von irgendwelchem user-input? _________________ "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 |
|
|
Raphael
Anmeldungsdatum: 17.03.2008 Beiträge: 18 Wohnort: Saarbrücken
|
Verfasst am: 04.04.2010, 16:21 Titel: |
|
|
Mmhhh, wie erkläre ich das jetzt...
Also, folgendes: es geht um ein Verwaltungsprogramm für ein Musikarchiv. Die Datensätze werden pro Tonträger abgelegt, wobei die Arten von Tonträgern unterschiedliche Meta-Daten haben. Die müssen über TYPE definiert werden. CDs und Platten haben dieselben Metadaten. Bei Kassetten oder MDs kommt aber die z.B. die maximale Aufnahmezeit dazu, bei MP3-Dateien noch Bitrate, Hertz, Speicherort und anderer Kleinkram. Bei sonstigen Tonträgern (z.B. Bänder, DATs oder andere Exoten) kommt noch viel mehr dazu.
Die Programmstruktur sieht vereinfacht gesagt so aus:
Frage: Was soll bearbeitet werden? CD, LP, MC, MD, Band...: [eingabe$]
Je nach Eingabe soll folgendes ausgeführt werden:
Zitat: | SELECT CASE eingabe$
CASE "CD"
TYPE cdtyp
obertitel AS STRING * 50
gesamtinterpret AS STRING * 50
titel$(1 TO 99) AS STRING * 44
interpret$(1 TO 99) AS STRING * 44
laenge$(1 TO 99) AS STRING * 5
END TYPE
DIM CDinhalt AS cdtyp
CASE "LP"
TYPE lptyp
obertitel AS STRING * 50
gesamtinterpret AS STRING * 50
titel$(1 TO 99) AS STRING * 44
interpret$(1 TO 99) AS STRING * 44
laenge$(1 TO 99) AS STRING * 5
END TYPE
DIM LPinhalt AS lptyp
CASE "MP3"
TYPE mp3typ
titel AS STRING * 50
interpret AS STRING * 50
kbit AS INTEGER
hz AS INTEGER
speicherort AS STRING* 80
END TYPE
DIM MP3inhalt AS mp3typ |
u.s.w.
Es soll also je nach Fall nur EIN solcher TYPE-Block ausgeführt werden. Die Methode mit SELECT CASE funktioniert aber nicht, ebenso alles andere, was ich schon probiert habe. QBX versucht immer, alle Variablen anzulegen, was natürlich schon bei einer Stringlänge von 44 * 3 * 99 (max. 99 Titel/Interpreten/Längen pro Tonträger mit je max. 44 Zeichen) heftig wird. Zumal auch gar nicht immer alle Variablen gebraucht werden, sondern eben immer nur die, die zu det gewünschten Tonträger-Art gehört.
(Einigermaßen verständlich?) |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 04.04.2010, 16:47 Titel: |
|
|
Hallo,
die Definition der User Defined Types (UDT) muss am Anfang des Programms außerhalb irgendwelcher Verzweigungen erfolgen. Die TYPEs sind schließlich nur "Backförmchen" bzw. Konstructionspläne (Der Rechtschreibfehler ist Absicht.), anhand derer du Variablen erstellen kannst, und sind selbst noch keine Variablen.
Innerhalb von SELECT CASE kannst du die Variablen dann deklarieren, wobei du die Bezeichner im Nachhinein nicht wiederverwenden kannst, d.h. CDinhalt könntest du nachher nicht mp3typ neu deklarieren, es sei denn du nimmst REDIM mit einem Array, dann sollte QBX das hinnehmen.
Code: | TYPE cdtyp
obertitel AS STRING * 50
gesamtinterpret AS STRING * 50
titel(1 TO 99) AS STRING * 44
interpret(1 TO 99) AS STRING * 44
laenge(1 TO 99) AS STRING * 5
END TYPE
TYPE lptyp
obertitel AS STRING * 50
gesamtinterpret AS STRING * 50
titel(1 TO 99) AS STRING * 44
interpret(1 TO 99) AS STRING * 44
laenge(1 TO 99) AS STRING * 5
END TYPE
TYPE mp3typ
titel AS STRING * 50
interpret AS STRING * 50
kbit AS INTEGER
hz AS INTEGER
speicherort AS STRING * 80
END TYPE
eingabe$ = "CD" 'als Beispiel
SELECT CASE eingabe$
CASE "CD": DIM CDinhalt AS cdtyp
CASE "LP": DIM LPinhalt AS lptyp
CASE "MP3": DIM MP3inhalt AS mp3typ
END SELECT
SLEEP |
Es fällt allerdings gleich auf den ersten Blick auf, wie unflexibel diese Herangehensweise ist. Wenn du schon auf eine Datenbank mit Abfragesprache verzichten möchtest, würde ich dringend ein Format wie XML für den Datenbestand verwenden, damit du nicht Unmengen an redundantem Code aufbauen musst. So musst du ja die meisten Management-Funktionen in dreifacher Ausfertigung - für alle drei "hard-gecodeten" Datensatz-Typen - umsetzen.
Übrigens: Bei Verwendung einer Programmierumgebung, über die du an 32-Bit-Binaries für Windows und/oder Linux gelangst (z.B. FreeBASIC, VB, gcc, ...), könntest du ohne Weiteres auch 500 MB große Arrays anlegen. Diese Kilobyte-Knebelung muss man sich heute wirklich nicht mehr antun, wenn man das nicht möchte.
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
Raphael
Anmeldungsdatum: 17.03.2008 Beiträge: 18 Wohnort: Saarbrücken
|
Verfasst am: 04.04.2010, 17:26 Titel: |
|
|
Danke für den Tip! Auf die Idee, einfach nur das DIM in die SELECT CASE-Abfrage zu setzen, bin ich gar nicht gekommen. Das probiere ich mal aus (heute aber nicht mehr, habe eine Woche Frühdienst hinter mir und den ganzen Nachmittag an dem Programm gesessen).
Klar, das mit der kB-Beschränkung nervt schon, und im Kern gebe ich Dir recht: das ganze sollte eigentlich schon 32 Bit-tauglich sein und eigentlich auch unter Windows/Linux/MacOS laufen. Nur möchte ich gerne das Programm erstmal unter DOS vollständig fertig machen, so daß es mit ISAM einwandfrei funktioniert und auf jedem Uralt-PC mit MS-DOS lauffähig ist. Wenn das alles klappt, steht irgendwann auch mal eine Ver-Windows-ung an, dann kann ich mir immer noch überlegen, wie ich ISAM in SQL oder XML konvertiere.
Erstmal sollte die neue DOS-Version laufen, damit habe ich erstmal genug zu tun. Sind übrigens 7 verschiedene Tonträgerarten mit noch viel mehr Backförmchen |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 04.04.2010, 19:51 Titel: |
|
|
auch DIM in den select-case blöcken wird nicht funktionieren da sie eigene scopes darstellen: was du in einem select case anlegst ist (zumindest bei normalen programmiersprachen) nach dem block wieder weg.
die richtige lösung ist es, die dims VOR den select case zu schreiben, und im select-case nur die Werte zuzuweisen. Alles andere ist programmiertechnisch einfach nur dumm, riskant und unlesbar. (und nein das soll nicht heißen dass du dumm bist, du weißts halt nur noch nicht besser ) _________________ "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 |
|
|
Raphael
Anmeldungsdatum: 17.03.2008 Beiträge: 18 Wohnort: Saarbrücken
|
Verfasst am: 05.04.2010, 08:48 Titel: |
|
|
Danke für die Blumen.
Die DIMs vor die SELECT CASE-Blöcke zu schreiben, wird aber auch nichts bringen, weil die Variablen ja feste Längen haben (... AS STRING * xx) und somit ohnehin schon gefüllt sind und demnach auch Speicher fressen. Ob da nur Leerzeichen drin stehen oder tatsächliche Werte, ist dem Speicher reichlich egal. Dein Lösungsansatz ist also auch nur ..., aber lassen wir das. |
|
Nach oben |
|
|
MOD Fleißiger Referenzredakteur
Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 05.04.2010, 11:10 Titel: |
|
|
Ich habe PDS nie verwendet, aber das wird doch auch Strings von variabler Länge haben. Lass das "* xx" nach der Deklaration weg und schon liegt nichts unnötiges im Speicher. |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4644 Wohnort: ~/
|
Verfasst am: 05.04.2010, 11:37 Titel: |
|
|
Wenn die Daten als kompletter Satz gespeichert werden sollen, werden UDTs mit Strings variabler Länge vermutlich Schwierigkeiten bereiten.
Ansonsten wäre es vielleicht besser, einen "Universal-UDT" zu definieren, der alle möglichen Tags enthält und vom dem dann nur immer die jeweils benötigten belegt und ausgewertet werden. Zum Speichern und Laden kannst du immer noch kurzfristig einen "Spezial-UDT" verwenden und die Daten dann per Hand in den universalen übertragen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 05.04.2010, 12:43 Titel: |
|
|
es geht ja nicht darum, den speicher möglichst spät zu allozieren. Du kannst speicher definitiv nicht im falschen scope allozieren, deswegen musst du die felder einfach vor dem select-block erstellen, sonst sind sie *eigentlich* danach wieder weg. das geht einfach nicht anders.
Alternativen dazu sind, dass du nen pointer erstellst vor dem select-block, und deinen string fester länge in dem block erstellst und dann den pointer zuweist. Freebasic unterstützts halt nicht, dass du sagst "ich hab nen string feld" und dann nachher sagst "ich speicher da jetzt ne string mit fixer länge 50 drin", das funktioniert mit der sprache einfach nicht. und ehrlich gesagt, von pointern würde ich dir schwer abraten wenn du noch nicht weißt wie man mit scopes richtig umgeht ;P
mein tip wäre, benutz einfach keinen fixed-length string. Mag beim speichern vielleicht klein wenig schwieriger sein, aber niemand hat gesagt programmieren wäre einfach deswegen scopes zu verletzen ist sicher nicht die richtige antwort. _________________ "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 |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 05.04.2010, 12:52 Titel: |
|
|
MisterD hat Folgendes geschrieben: | Freebasic unterstützts halt nicht |
Er nutzt doch auch QBasic (QBX 7.1 alias PDS).
Ich habe das Beispiel jetzt mal auf die Schnelle getestet und denke, dass die innerhalb der CASEs deklarierten Variablen auch außerhalb davon Gültigkeit behalten. QBasic scheint abgesehen von Hauptprogramm und Prozeduren keine weitere Scope-Abgrenzung zu haben.
MisterD hat Folgendes geschrieben: | von pointern würde ich dir schwer abraten |
Pointer spielten in QB, wenn ich das richtig in Erinnerung habe, überhaupt keine Rolle. Für Spezialfälle gab es zwar sowas wie VARPTR, aber so umfassend wie in FreeBASIC kann man in QB davon nicht Gebrauch machen. _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 05.04.2010, 13:14 Titel: |
|
|
oi stimmt forum verwechselt sry ;P
naja in dem fall .. schweinerei von ms ma wieder dass qb select-blöcke nicht scoped.. x) aber was will man tun _________________ "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 |
|
|
Raphael
Anmeldungsdatum: 17.03.2008 Beiträge: 18 Wohnort: Saarbrücken
|
Verfasst am: 05.04.2010, 13:29 Titel: |
|
|
MisterD hat Folgendes geschrieben: | aber was will man tun |
Kleiner Tip: erstmal lesen und verstehen, worum es eigentlich geht
Im Ernst: Strings mit variabler Länge sind bei ISAM nicht erlaubt. Deshalb muß ich innerhalb von TYPE...END TYPE nunmal feste Längen anlegen, egal, ob die komplett ausgereizt werden oder nicht.
Parallel zu diesem Thread hier habe ich selbst ein wenig herumprobiert und bin am Samstag abend auf die Idee gekommen, die nemored hier angesprochen hat: ein TYPE-Block mit allen erforderlichen Variablen drin. Um Speicherplatz zu sparen, teilen sich verschiedene Tonträgerarten einige Variablennamen. Funktioniert wunderbar.
Übrigens, MisterD: ich programmiere seit 1993 in QB, bin also alles andere als ein Anfänger, von daher ist Dein leicht überheblicher Ton ("dumm, riskant und unlesbar", "wenn du noch nicht weißt wie man mit scopes richtig umgeht") ziemlich daneben. |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 05.04.2010, 13:45 Titel: |
|
|
meine güte ich hab doch extra dazugeschrieben dass das NICHT heißen soll, dass DU dumm bist, warum drehst du das jetzt noch extra um?
es ist nunmal nur einfach so, dass du da scopes verletzt, zumindest nach heutigem programmierstand. Vielleicht war das gang und gebe programmierpraxis damals als das möglich gemacht wurde, das mag sein, aber ich sage ja nur es ist verdammt ungesund es absichtlich so zu benutzen wenns anders geht. Wenns nicht anders geht .. nja dann ists halt blöd, aber solangs anders geht sollte man es möglichst wenig fehleranfällig machen - und das ist einfach indem man die variablen ordentlich im richtigen scope definiert und dann in dem kleineren scope nurnoch mit werten füllt. Ich versuch hier auch nur zu helfen. _________________ "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 |
|
|
Raphael
Anmeldungsdatum: 17.03.2008 Beiträge: 18 Wohnort: Saarbrücken
|
Verfasst am: 06.04.2010, 14:29 Titel: |
|
|
Also gut, lassen wir diese Scopes beiseite. Funktioniert ja inzwischen auch bzw. habe ich eine Möglichkeit gefunden, das Problem zu lösen.
Mal was ganz anderes: gibt es ein Tool, mit dem man sozusagen in die ISAM-Dateien hineinschauen kann? Quasi eine Art Viewer, in dem die Indizes mit ihren Werten tabellenförmig aufgedröselt sind? Die Tools, die bei QBX dabei sind, bieten sowas nicht, und im Internet habe ich auch nichts gefunden. Schön wäre noch, wenn man über ein solches Tool auch die Inhalte ändern kann. Muß aber nicht zwingend, ein halbwegs komfortabler Betrachter wäre schonmal ein Fortschritt.
Ggf. kann ich dazu aber auch ein neues Topic eröffnen. |
|
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.
|
|