| Hallo.
ich schrieb hier Anfang Januar:
> [Es gibt von mir seit einiger Zeit ein 32-Bit-Programm namens
> "DirType.exe", das eine Textdatei namens "dirtype.txt" erstellt,
> in die es die langen Dateinamen des aktuellen Verzeichnisses
> schreibt.]
Und nun gibt es eine neue Version, die wahlweise
- *nur* Dateinamen,
- *nur* Unterverzechnisse oder
- Unterverzeichnisse *und* Dateinamen
auflistet.
Das Programm hat nun eine kurze Hilfeseite/Selbstauskunft, die
angezeigt wird, wenn das Programm gestartet wird mit
dirtype ?
Weiterhin kann der Anwender nun, so er möchte, den Namen der
Ausgabedatei selbst bestimmen, dann startet er DirType 2.0 bspw.:
dirtype -files meineDateien.txt
Ein Ergebnis / eine Ausgabedatei von DirType 2.0 kann bspw. so
aussehen:
----- Dateianfang: ---------------------------
Unterverzeichnisse und Dateien im Verzeichnis
D:\Corel\Paint\Gerasterter Text
am 26.02.2005 um 13 Uhr 47 Minuten 31 Sekunden:
<DIR> Wer kennt diesen Effekt-Dateien
Wer kennt diesen Effekt.htm
Wer kennt diesen Text-Effekt.txt
----- Dateiende: -----------------------------
Das Programm liegt online in der Rubrik "DOS", die auch
Windowsprogramme behandelt, der "Chat Noir" oder kann von mir
per E-Mail abgefragt werden.
Gruß elek Gut, Fred, kommt per E-Mail.
Leider habe ich ein paar Dateien auf meinem Computer gelöscht, ich
habe aber einen alten Quellkode wiedergefunden und neu kompiliert:
Die Programmversion funktioniert, soweit ich sehe.
(Mir liegt ein älteres Kompilat kleinerer Größe vor, ob es einen
relevanten Unterschied in der Arbeitsweise gibt, weiß ich leider
nicht mehr; da ich das Programm vor ca. 3 Jahren geschrieben habe.
Ich vermute, es gibt nur minimale Unterschiede, die für den Anwender
keine Rolle spielen.)
Gruß elek Hallo
Ich habe gelesen, du haettest
ein Programm entwickelt, das
die langen Namen ausliest.
Wuerdest du mir dieses ebenfalls
senden?
Liebe Gruesse von Fred Hari
Beundenacker 7
CH-3373 HEIMENHAUSEN Hallo Thorsten! Mit GFA-BAS habe ich einige Versuche auf Windows XP
vorgenommen. GFA läuft sehr gut. Was machst Du so am PC? Schreib mich
bitte einmal an. Gruss Leo, leopaul@arcor.de Problemlösung / Hilfe
Das nachstehende Programm und die Hinweise sind in
keiner Weise privat zu nutzen! Keinerlei Haftung! Schreibfehler
bitte ingnorieren!
Das nachstehende Programm ist das System VEW 609,
6 aus 9, 6 Zahlen aus 9 mit einer bestimmten Garantie.
Es wird von den Lottogesellschaften in einer Broschüre
angeboten. Gibt man hier die Zahlen in der Reihenfolge
von 1 bis 9 ein, so erhält man als Darstellung das System.
Reihe 1 = 1,2,3,4,5,6
Reihe 2 = 1,2,3,4,7,8
Reihe 3 = 1,2,3,6,7,9
Reihe 4 = 1 2,4,5,8,9,
Reihe 5 = 1,2,5,6,7,8
Reihe 6 = 1,3,4,6,8,9
Reihe 7 = 1,3,5,7,8,9
Reihe 8 = 1,4,5,6,7,9
Reihe 9 = 2,3,4,5,7,9
Reihe 10 = 2,3,5,6,8,9
Reihe 11 = 2,4,6,7,8,9
Reihe 12 = 3,4,5,6,7,8
Will man dieses System mit einer anderen Zahlenreihe
nutzen, so muß man für jede entsprechend Systemzahl
die direkt betreffende andere Zahl eingeben. Siehe
folgendes Beispiel: Zahlenreihe:
2,17,18,22,27,29,38,45,49
Sieht man dann die Auswertung, so kann man nur mit
ganz großen Schwierigkeiten die gezogenen Zahlen
erkennen. Hier kann man nun einen Trick anwenden.
Gehen wir davon aus, dass folgende Zahlen gezogen
wurden: 18,27,38,49. Dann die Zahlenreihe wie folgt
eingeben: 0,0,18,0,27,0,38,0,49. Die (0) Nuller sind
Ersatz für nicht gezogene Zahlen. Dieser Trick ist aber
nicht zufrieden stellend.
Folgendes Problem ist zu lösen: Bei dem Versuch
Zahlenreihen auszuwerten sollen am Anfang der
Auswertung die gezogenen Zahlen eingegeben werden.
Diese Zahlen sollen dann im System farbig dargestellt
werden. So auch in Verbindung mit mehreren Zahlenreihen.
Wenn Sie mir helfen könnten, dieses Problem zu lösen,
wäre ich Ihnen sehr dankbar. Beiderseitige Forderungen
sind ausgeschlossen. Die Lösungen gehen in meinen
Besitz über und werden bei Bedarf weiter gegeben.
Ich bin dabei, eine Webseite für die Programmierung
mit GFA-DOS und Webseitenbau zu erstellen. Dort werde
ich auch die Auswertung von weiteren Lotto-Systemen
beibehalten. Sollten Sie an meiner Webseite Interesse
bekommen, melden Sie sich bitte schon, auch wenn die
WS noch nicht fertig ist. Gruß Leo, leopaul@arcor.de
Dieses fertige QB... ,bas-Programm kann bei mir angefordert
werden. Bearbeitung in der Reihenfolge des Posteingangs.
-------------------------------------------------------------------------
----
CLS
INPUT "Bitte 1. Zahl eingeben ", a1
INPUT "Bitte 2. Zahl eingeben ", a2
INPUT "Bitte 3. Zahl eingeben ", a3
INPUT "Bitte 4. Zahl eingeben ", a4
INPUT "Bitte 5. Zahl eingeben ", a5
INPUT "Bitte 6. Zahl eingeben ", a6
INPUT "Bitte 7. Zahl eingeben ", a7
INPUT "Bitte 8. Zahl eingeben ", a8
INPUT "Bitte 9. Zahl eingeben ", a9
INPUT "Bitte 10. Zahl eingeben ", a10
INPUT "Bitte 11. Zahl eingeben ", a11
INPUT "Bitte 12. Zahl eingeben ", a12
CLS
LOCATE 10, 10: PRINT " Auswertung System VEW 609 / 6 aus 9 / 12 Reihen"
LOCATE 11, 10: PRINT
LOCATE 13, 10: PRINT " Zahl 1/": LOCATE 13, 24:
PRINT USING "####"; a1; a1; a1; a1; a1; a1; a1; a1; a2; a2; a2; a3
LOCATE 14, 10: PRINT " Zahl 2/": LOCATE 14, 24:
PRINT USING "####"; a2; a2; a2; a2; a2; a3; a3; a4; a3; a3; a4; a4
LOCATE 15, 10: PRINT " Zahl 3/": LOCATE 15, 24:
PRINT USING "####"; a3; a3; a3; a4; a5; a4; a5; a5; a4; a5; a6; a5
LOCATE 16, 10: PRINT " Zahl 4/": LOCATE 16, 24:
PRINT USING "####"; a4; a4; a6; a5; a6; a6; a7; a6; a5; a6; a7; a6
LOCATE 17, 10: PRINT " Zahl 5/": LOCATE 17, 24:
PRINT USING "####"; a5; a7; a7; a8; a7; a8; a8; a7; a7; a8; a8; a7
LOCATE 18, 10: PRINT " Zahl 6/": LOCATE 18, 24:
PRINT USING "####"; a6; a8; a9; a9; a8; a9; a9; a9; a9; a9; a9; a8
LOCATE 19, 10: PRINT " --- --- --- --- --- --- --- --- ---
--- --- ---"
LOCATE 20, 10: PRINT " Zeile Nr/ 1 2 3 4 5 6 7 8 9
10 11 12"
END Guten Tag,
unsere Firma benutzt als Programm auch ein Gfa Basic programmiertes System, habe
n Sie Möglichkeiten herausgefunden wie es unter XP läuft. Über eine Antwort wäre
ich sehr erfreut.
Mit bestem Dank
Thorsten Balzer Hallo Siegmund!
ich schrieb:
> Probiere also z. B. als Erstes aus, was Dir WindowsXP anzeigt,
> wenn Du den Parameter "/V" benutzt:
>
> SHELL "dir *.* /V>1.txt"
Ansonsten gibt es von mir übrigens seit einiger Zeit schon ein
einfaches 32-Bit-Programm namens "DirType.exe", das nach Aufruf eine
Textdatei namens "dirtype.txt" erstellt, in der dann die langen
Dateinamen des aktuellen Verzeichnisses stehen. Das Ergebnis sieht
beispielsweise so aus:
----- Dateianfang: ---------------------------
Dateien im Verzeichnis
C:\XPoint\EXTRACT
am 01-01-2005 um 00:02:56 Uhr.
ASC2ANSI.exe
CRLF_reduce.exe
CYGWIN.HAP
EXTRACT.J
FAVICON.J
HTML_Files.zip
JPGS.SQZ
Kursunterlagen.tgz
PROGLERN.J
PUFS.HAP
SH_CMD.EXE
ZELL_PNG.SQZ
----- Dateiende: -----------------------------
Das Programm liegt online in der "Chat Noir" oder kann von mir per
E-Mail abgefragt werden.
Gruß elek Hallo Siegmund,
Beachte auch die Hilfe des Kommandointerpreters, wenn Du am Prompt
eingibst:
DIR /?
Unter Windows 95 erscheint dann:
"Zeigt die Dateien und Unterverzeichnisse eines Verzeichnisses an.
DIR [Laufwerk:][Pfad][Dateiname] [/P] [/W] [/A[[:]Attribute]]
[/O[[:]Sortierfolge]] [/S] [/B] [/L] [/V]
[Laufwerk:][Pfad][Dateiname]
Anzuzeigendes Laufwerk, Verzeichnis bzw. Dateien.
(Erweiterte oder mehrere Dateiangaben sind zulässig.)
[...]
/B Verwendet einfaches Format (kein Vorspann und keine
Zusammenfassung).
/L Verwendet Kleinschreibung.
/V Aktiviert die ausführliche Anzeige.
Optionen können in der Umgebungsvariablen DIRCMD voreingestellt werden.
- vor einer Option deaktiviert die Voreinstellung, z.B. /-W."
Möglicherweise ist einfach die Umgebungsvariable DIRCMD auf einen
für Dich ungünstigen Wert gesetzt, das könntest Du einfach dadurch
aushebeln, daß Du die gewünschten Parameter ausdrücklich und direkt
mit dem SHELL-Befehl hinter "DIR" angibst.
Probiere also z. B. als Erstes aus, was Dir WindowsXP anzeigt, wenn
Du den Parameter "/V" benutzt:
SHELL "dir *.* /V>1.txt"
HTH elek Hallo Siegmund!
Siegmund Wagner am 29.12.04 / 10:20 (Mittwoch):
> Hallo Turbo Basic Freunde!
> Problem:
> Lange Dateinamen in Turbo Basic SHELL Befehl auf WindowsXP
>
> [...]
>
> Frage:
> Welche Einstellungen in autoexec.nt, config.nt oder andere muss
> man dazu vornehmen?
Das kann ich momentan nicht genau sagen, da ich persoenlich nicht
unter Windows XP arbeite, allerdings weiss ich, von folgendem
Eintrag fuer die <autoexec.bat>, der zumindest in aelteren 32-Bit-
Windows-Versionen gebraeuchlich war:
SET LFN=y
HTH und "Guten Rutsch!"
elek Hallo Turbo Basic Freunde!
Problem: Lange Dateinamen in Turbo Basic SHELL Befehl auf WindowsXP
Auf Windows98 konnten beim Turbo Basic Befehl:
shell "dir *.* > 1.txt"
die langen Verzeichnis- und Dateinamen in 1.txt geschrieben werden.
Bei WindowsXP geling es, wenn der Befehl "dir *.* > 1.txt" direkt von
DOS Ebene oder einer BAT-Datei herausgeht. Bei Turbo Basic SHELL
erscheinen leider nur die kurzen Dateinamen 8+3.
Frage: Welche Einstellungen in autoexec.nt, config.nt oder andere muss
man dazu vornehmen?
Für Eure Hilfe herzlichen Dank.
Grüße Daniel Wagner
E-Mail: SIEWAG@t-online.de Hallo Turbo Basic Freunde!
Problem: Lange Dateinamen in Turbo Basic SHELL Befehl auf WindowsXP
Auf Windows98 konnten beim Turbo Basic Befehl:
shell "dir *.* > 1.txt"
die langen Verzeichnis- und Dateinamen in 1.txt geschrieben werden.
Bei WindowsXP geling es, wenn der Befehl "dir *.* > 1.txt" direkt von
DOS Ebene oder einer BAT-Datei herausgeht. Bei Turbo Basic SHELL
erscheinen leider nur die kurzen Dateinamen 8+3.
Frage: Welche Einstellungen in autoexec.nt, config.nt oder andere muss
man dazu vornehmen?
Für Eure Hilfe herzlichen Dank.
Grüße Daniel Wagner
E-Mail: SIEWAG@t-online.de Hallo Kristina Wetzke.
Kristina Wetzke am 20.01.04 / 10:39 (Dienstag):
> :-) Hi!!!
Ja. Tach. :-)
> Was sind den überhaupt Metabefehle!!
Ich versuche nur zu erklären, wie *ich* das Wort Metabefehl
verstehe.
Eines ersten Wörter mit der Vorsilbe "Meta", das ich, soweit ich
mich erinnere, bewußt gelernt habe, war "Metakommunikation" und
Metakommunikation bedeutet
"Kommunikation über Kommunikation".
Entsprechend verstehe ich unter einem Metabefehl einen
Befehl zu einem Befehl.
Also einen Befehl, der einzig den Zweck hat, einen Befehl (oder
mehrere) näher zu bestimmen, also wäre ein Metabefehl ein Befehl der
bestimmt, wie einzelne folgende Befehle auszuwerten sind.
Ich vermute, daß Deine Frage an meinen hiesigen Beitrag
<http://www.chatnoir.de/foren/w3.basic.htm#111091>
vom 05.09.03 anschließt, in dem ich schrieb:
> [...]
>
> Damit die Zeile gefunden wird, in der ein Laufzeitfehler
> tatsächlich verursacht wurde, muß in PowerBASIC für DOS der
> Compiler-Befehl "$Error All on" gesetzt sein.
>
> [ Ich hatte diesen *Metabefehl* während der Programmentwicklung
> Programmversion schon aktiviert hatte. ] [...]
>
> [...]
Konkreter als "Metabefehl" ist in diesem Zusammenhang
die Bezeichnung "Compiler-Befehl", "$Error all on" ist ein Befehl
an den Compiler, daß dieser für bestimmte Befehle und Situationen
zusätzlichen Kode zum Abfangen von Laufzeitfehlern erzeugen soll.
Tritt in einen PowerBASIC-Programm beispielsweise der Befehl auf,
ein Array zu lesen (Array: eine eindimensionale Liste, deren Felder
über einen Index, über einfache ganze Zahlen angesprochen wird), so
bewirkt "$Error all on", daß zusätzlicher Kode generiert wird, der
bei jeder Array-Abfrage überprüft, ob der gerade benutzte Indexwert
für das Array aus dem Bereich der erlaubten Werte ist (nicht zu groß
/ zu klein ist).
Der Compiler-Befehl "$Error all on" befiehlt dem Compiler also
u. a., wie ein Array-Zugriffsbefehl auszulegen ist.
Jetzt noch ganz offiziell:
<zum Bücherregal geh>
...
"Metastatements operieren auf einer anderen Ebene als
normale Befehle, Sie gehören eigentlich nicht zum Programm,
sondern sind Befehle für den Compiler (deshalb werden sie
auch »Compilerdirektive« genannt). Metastatements beginnen
[in PowerBASIC für DOS] immer mit einem Dollarzeichen (»$«).
Standard-Befehle kontrollieren den Rechner zur Laufzeit;
Metastatements steuern den Compiler zur Kompilierzeit [...]"
( Aus "PowerBASIC Benutzer-Handbuch" Kirschbaum Software,
1993; d. i. ein Teil der Dokumentation zu PB/DOS 3.0 )
Hoffe, es paßt so.
Gruß elek :-) Hi!!!
Was sind den überhaupt Metabefehle!!
:-) MfG Kris :-) Hallo Sven!
Ich habe überlesen, daß Du GwBasic schon hast. Um den Quelltext als
ASCII-Datei zu speichern, gehe wie folgt vor:
- Starte <GwBasic.exe>.
- Drücke [F3]. Daraufhin erscheint *Load"* am Bildschirm.
- Ergänze dies etwa *Load"programm.bas" [Enter]
- Drücke nun [F4], um den Quelltext als ASCII-Datei zu speichern.
Es erscheint *Save"* am Bildschirm.
- Ergänze dies etwa zu *Save"program2", A* [Enter]
- Du findest nun eine ASCII-Datei namens <program2.bas>
auf der Festplatte.
Gruß elek Also, gwbasic hab ich ja, wie gesacht, selbst. nur kann ich da ja nur
die
letzten ~ zeilen sehn, und die anderen zeilen stehn halt oben drüber
und
sind nicht mehr erreichbar, da das fenster von gwbasic bei mir nicht
größenveränderbar ist.
Aber wie ist denn deine email-addy? Hallo Sven!
Schick mir das Ding per E-Mail, dann extrahiere ich Dir das.
Alternative: besorge Dir GWBASIC und extrahiere es selbst.
Gruß elek Modern im sinne von läuft auf xp und net auf nem c64 ^^ modernes VBA ..... *g*
_________________________________________________________________
Wußten Sie, daß Sie Ihren Hotmail-Posteingang auch über den MSN Messenger
abrufen können? http://messenger.msn.de Jetzt kostenlos downloaden und
einfach testen! Hi!
Ich muss unbedingt an den quellcode einer .bas Datei, geschrieben mit
gwbasic.mit anderen programmen geöffnet erscheint nur datensalat,
bei der
Gwbasic.exe kann ich ja nicht scrollen und somit sehe ich nur die
letzten ~
15 zeilen.wie komm ich an diesen quellcode ran? Weil ich muss darauf
nen
modernes VBA programm schreiben.
Vielen Dank im vorraus für die Hilfe
Sven Hallo!
Ein Vorzug von Perl sind vielfältige Manipulationsmöglichkeiten an Strings,
insbesondere mit Regulären Ausdrücken.
Ein einfacher und dabei sehr wirkungsvoller Kode wird gelegentlich als
elegant bezeichnet. In einem neueren Usenet-Beitrag fand ich zwei in diesem
Sinne elegante Arten alle Zahlen in einem String durch ihr Quadrat zu
ersetzen:
*Perl*
$s =~ /(\d+)/$1*$1/ge;
*SNOBOL4* (geht seit 1969)
s ? digits $ n rpos(0) = n * n
Als Knobelei für den späten Abend habe ich mir die Aufgabe gestellt, solche
Ersetzungen ebenso elegant in PowerBASIC erledigen zu können.
Und es geht doch!
*PowerBASIC Console Compiler 3*
test$ = ExprRepl$( "[0-9]+", test$, CodePtr(Quadrat$) )
Dazu habe ich eine Function ExprRepl$() kodiert, die das meiste erledigt.
Der Programmierer braucht nur noch eine Function zu definieren, welche die
Manipulation vornimmt, die er an dem Textteil vornehmen lassen möchte,
welcher durch den Regulären Ausdruck (im Beispiel "[0-9]+" selektiert wird.
Diese Funtkion muß einen String zurückgeben. Außerdem muß, wie unten zu
sehen, eine Function namens dummy$() deklariert werden.
----- Kode-Anfang --------------------------------------------------
#IF 0
Dieses Demo-Programm schreibt folgende Bildschirmausgabe:
heute ist 3 plus 4 gleich 8.
heute ist 9 plus 16 gleich 64.
heute ist 4.5 plus 8 gleich 32.
#ENDIF
Declare Function ExprRepl$ (String, String, Long)
Declare Function Quadrat$ (String)
Declare Function Haelfte$ (String)
Declare Function dummy$ (String)
Function PbMain()
Color 1, 15
Cls
?
test$ = "heute ist 3 plus 4 gleich 8."
? test$
test$ = ExprRepl$( "[0-9]+", test$, CodePtr(Quadrat$) )
? test$
test$ = ExprRepl$( "[0-9]+", test$, CodePtr(Haelfte$) )
? test$
WaitKey$
End Function
Function ExprRepl$ ( expr As String, text As String, ptrFn As Long ) Private
Do
RegExpr expr$ in text at start& to iPos&, iLen&
If IsTrue iPos& Then
Call DWord ptrFn& Using dummy$( Mid$(text, iPos&, iLen&) ) to result$
text$ = Left$( text$, Max&(0, iPos&-1) ) +_
result$ +_
Mid$( text$, iPos&+iLen& )
start& = iPos& + Len( result$ )
End If
Loop Until IsFalse iPos& Or start& >= Len(text)
Function = text
End Function 'ExprRepl$ ()
Function Quadrat$( numText As String ) Local Private
Function = Format$( Val( numText ) ^ 2 )
End Function 'Quadrat$()
Function Haelfte$( numText As String ) Local Private
Function = Format$( Val( numText ) / 2 )
End Function 'Haelfte$()
----- Kode-Ende ----------------------------------------------------
regards elec Hallo Programmierer!
Der kürzlich von mir hier angesprochene Fehler war kein Bug
der Programmiersprache (PB/DOS 3.5).
Ich weiß, daß es viele Leute gibt, in Foren lesen, aber
selber nie oder kaum etwas schreiben. Für alle schweigenden,
aber vielleicht irgendwann einmal hilfesuchenden PowerBASIC-
Anwender schreibe ich diese kurze Erläuterung.
Damit die Zeile gefunden wird, in der ein Laufzeitfehler
tatsächlich verursacht wurde, muß in PowerBASIC für DOS der
Compiler-Befehl "$Error All on" gesetzt sein.
Die Tücke des Objekts lang in meinem Fall darin, daß ich
diesen Metabefehl während der Entwicklung der neuen Version
meines Programms HeaDel, das ich gerade von PB 3.2 nach PB
3.5 portiert habe, schon aktiviert hatte. Was? Hilft "$Error
All on" doch nicht?
Doch, es hilft, nur verwendet mein Programm einige selbst
programmierte Units, in einer stand "$Error All off".
Deshalb konnte die PowerBASIC IDE den Fehlerort (eben genau
in dieser Unit) nicht bestimmen.
------------------------------------------------
*Unit*
schon kompilierte Binärdatei, die bei der
Kompilation des Hauptprogramms in das Programm
eingebunden wird.
Sinn von Units ist die Wiederverwertung
eines Bausteins in mehreren Programmen und
die Beschleunigung des Kompilierens, da
die Unit nicht mehr kompiliert werden muß,
sondern nur noch ins Programm aufgenommen.
------------------------------------------------
Ich rate Euch also dringend, wenn Ihr die Ursache von
mysteriösen Laufzeitfehlern sucht, *zuerst* den Compiler-
Befehl "$Error All on" ins Hauptprogramm *und* in alle
Unit- und Library-Quellkodes zu schreiben. (Die Units und
Libraries müssen dann freilich gleich einzeln neu kompiliert
werden.)
Diese Vorgehensweise kann Euch sehr viel Arbeit ersparen.
Viel Freude und Erfolg!
elek Hallo!
> Weiß jemand ob es in PowerBASIC [PB/DOS 3.5] einen Bug gibt,
> der Fehlermeldungen hervorruft vorzugsweise, sobald die
> Funktion "Val()" angewandt wird? Es entsteht ein
> Laufzeitfehler #11 (devision by zero) [...]
Das Problem ist geklärt. Es handelt sich nicht um einen Bug
von PB. Falls jemand weitere Details über das Debugging in
diesme Fall erfahren möchte, bitte fragen!
Gruss elek Hallo.
Weiß jemand ob es in PowerBASIC [PB/DOS 3.5] einen Bug gibt,
der Fehlermeldungen hervorruft vorzugsweise, sobald die
Funktion "Val()" angewandt wird? Es entsteht ein
Laufzeitfehler #11 (devision by zero), selbst in Fällen, in
denen ich ganz offensichtlich weder eine falsche noch eine
komplexe Zuweisung mit "Val()" veranlasse.
Versuchsweise habe ich sogar
longInt& = Val( "11111" )
eingesetzt. Das Programm bricht auch dann an dieser Stelle,
sobald es auf das "Val()" trifft mit oben erwähntem, Error
#11 ab.
Ich finde bisher keine Erklärung oder Lösung, weder in der
PbGer-FAQ noch in den Handbüchern und auch bei der Arbeit am
Quelltext nicht.
Gruß elek Hallo!
Thema heute: *Dynamische Arrays in PowerBASIC für DOS zurücksetzen*
Ein Array, das zur Compilier-Zeit angelegt wird, kann In PowerBASIC
für DOS jederzeit mit dem Befehl ERASE zurückgesetzt werden, so daß
beispielsweise ein String-Array danach nur noch Leer-Strings enthaelt.
Das Gleiche klappt aber nicht mit dynamischen Arrays, also solchen,
für die erst zur Programmlaufzeit Speicher bereitgestellt wird.
Dynamische Arrays werden durch den Befehl ERASE komplett beseitigt.
In den neueren BASIC-Dialekten PB/CC bzw. PB/Win lassen sich auch
dynamische Arrays leicht zurücksetzen. Dazu dient der Befehl ReSet,
der einer der wenigen Befehle ist, der in PowerBASIC für Windows
eine ganz andere Funktion hat als in PowerBASIC für DOS.
----- Zitat aus der Online-Hilfe von PB/CC 3.0 --------
*Aufgabe* Setzt eine skalare Variable, ein Variant,
einen anwenderdefinierten Datentyp, ein ein-
zelnes Array-Element oder ein ganzes Array
auf den Wert 0 oder leer" RESET entfernt
die Variable o. dgl. nicht aus dem Speicher.
*Syntax* RESET variable
RESET array()
RESET array(subscript)
----- Zitatende -- (c) PowerBASIC Inc. -----------------
Sehr leicht läßt sich das Gleiche allerdings auch in PowerBASIC für
DOS durch zwei aufeinander folgende Befehlszeilen erreichen:
arrSize& = UBound( myArray$ )
ReDim myArray$( arrSize% )
Falls man dies durch einen einzelnen Befehl ersetzen möchte, ist
beispielsweise folgendes Vorgehen möglich:
1. Eine einfache Quelltextdatei folgenden Inhalts in das Include-
Verzeichnis schreiben:
----- Beginn der Include-Datei "arrReset.inc" ---------
' Loescht den Inhalt aller Array-Elemente
'
Sub resetStrArray( myArray(1) As String ) Local Public
Local i&
For i&=UBound(myArray$) To LBound(myArray$) Step -1
Array Delete myArray$(i&)
Next i&
End Sub
----- Ende der Include-Datei --------------------------
2. In jedes Programm, das die neue Funktion nutzen soll, schreibt
man vor das eigentliche Hauptprogramm den Compiler-Befehl,
welcher diesen Programmschnipsel in die Kompilation einbezieht:
$INCLUDE "arrReset.inc"
3. Im Programm kann nun ein eindimensionales String-Array durch
einen der beiden folgenden Befehle mit Leer-Strings belegt
werden:
Call resetStrArray( arrayName$() )
resetStrArray arrayName$()
4. Demonstrieren / Testen könnt Ihr die Funktion mit folgendem
einfachen Beispielprogramm:
------- Kode-Anfang ---------------------------------
$Include "arrReset.inc"
Color 1, 15
Cls
Dim zahlen$(4)
For i%=0 To 4
Read zahlen$(i%)
Next i%
For i%=LBound(zahlen$) To UBound(zahlen$)
Print Chr$(34); zahlen$(i%); Chr$(34),
Next i%
resetStrArr zahlen$()
?
For i%=LBound(zahlen$) To UBound(zahlen$)
Print Chr$(34); zahlen$(i%); Chr$(34),
Next i%
Sleep 40
Data eins, zwei, drei, vier, fuenf
End
------- Kode-Ende -----------------------------------
Viel Spaß und Erfolg beim Kodieren wünscht
Elek Hallo!
Hat jemand sich schon mal genauer mit PowerBASICs Befehl "Array Scan"
beschäftigt und diesen Befehl auf zwei- oder mehrdimensionale Arrays
losgelassen?
Ich hab' bei sowas zur Zeit sporadische Fehler um den Wert eins.
Ich werd' daraus im Moment nicht schlau.
Gruss elek Hallo BASIC-Programmierer!
Heute eine kleine Funktion für 32-Bit-PowerBASIC, welche die Dateiendung
einer Dateiangabe zurueckgibt.
*Erläuterungen*
Bezeichner, die mit einem Dollarzeichen beginnen sind in 32-Bit-PowerBASIC
Namen von String-Konstanten. Im vorliegenden Beispiel:
$Spc ist ein Leerzeichen, also Chr$(32)
$Tab ist Chr$(9)
$Dq steht für Double-quote, also für Chr$(34)
Weitere Fragen bin ich bereit zu beantworten.
Verbesserungsvorschläge oder alternativer Kode in anderen BASIC-Dialekten
wären auch toll.
Viel Spaß und Erfolg beim Kodieren wünscht
Elek
#If 0
--------------------------------------------------------------------------
Modul ............ handleFilenames.inc
Aufgabe .......... Stringfunktionen zur Behanldung von Dateinamen
Compiler/Sprache .. PB/CC 3.x
Abgeleitet aus den Routinen zur Datei und Verzeichnisbehandlung
fuer PB 3.20 "dirnfile.bas" vom 06.06.2002, 05:03 Uhr.
Stand ............ Samstag, 09.08.2003, 13:10 Uhr
Programmautor .... elek
--------------------------------------------------------------------------
#EndIf
'[...]
Function getExtension$( file$ )
'
' Liefert die Dateiextension, falls die Angabe ein Dateiname mit oder
' ohne davor stehender Pfadangabe ist.
'
' 09.08.2003
'
Local filesName As String
Local extension$
file$ = Trim$( file$, Any $Spc+$Tab+$Dq )
'PFAD ENTFERNEN:
filesName = Parse$( file$, "\", ParseCount(file$, "\") )
'EXTENSION EXTRAHIEREN:
extension$ = IIf$( IsFalse InStr(filesName, "."), "", _
Parse$(filesName, ".", ParseCount(filesName, ".") ) _
)
Function = extension$
End Function 'getExtension$()
'----------- Ende des Modul-Auschnitts ----------------------------- Hallo!
PowerBASIC Inc. stellt seit Kurzem für registrierte Nutzer der
letzten Compiler-Versionen ein kostenloses Update zum Download
bereit. Damit erreicht PowerBASIC for Windows die Version 7.02 und
der PowerBASIC Console Compiler die Version 3.02.
Registrierte bekommen per E-Mail die nötigen Zugangsdaten.
Gruss elek Hallo, ich heiße Dajana und habe eine dringende Frage!
Ich muss für die Schule ein Qbasic Programm mit Hilfe des Datentyps
Array schreiben.Es soll mit dem Programm möglich sein, CD's zu
archivieren. Es soll folgender maßen aufgebaut sein:
- der Benutzer wird gefragt, wie viele CD's er archivieren möchte und
wie viele daten er zu jeder Cd archivieren möchte (Titel der CD ,
Preis...)
- Dann kann er sich mit hilfe einer tabelle alle seine eingetragenen
daten ansehen
- wenn er möchte kann er diese Daten ergänzen oder ändern
- er soll sie über ein unterprogramm suchen können
- und die Cd's müssen nach Anfangsbuchstaben sortiert werden
Kannst du mir helfen? Ich sehe überhaupt nicht durch und muss morgen
fertig sein mit dem Programm! Josef Kirschbaum [jk@powerbasic.de] schrieb mir:
jeder BASIC-Compiler setzt den BASIC-Quellcode
in Machinensprache um. Man kann zwar diesen
generierten Code analysieren und mit Hilfe
entsprechender Werkzeuge in Teilbereichen
als Assembler-Quellcode darstellen. Eine
Rückverwandlung in den ursprünglichen
BASIC Quellcode ist technisch nicht möglich!
In Ihrer Situation ist dies sicher bedauerlich!
Wer als Programmierer jedoch Wochen und Monate
in die Entwicklung eines Projektes investiert
hat, würde sicher nicht glücklich darüber sein,
wenn jedermann aus einer fertigen EXE-Datei
den ursprünglichen Quellcode erzeugen könnte.
Sollten Sie tatsächlich noch mit Turbo-BASIC
programmieren, so kann ich Ihnen nur aus voller
Überzeugung raten, auf das Nachfolgeprodukt
PowerBASIC umzusteigen!
Sie finden auf unserer Homepage und ausführlicher
noch im deutschsprachigen PowerBASIC Forum viele
weitere Informationen zu PowerBASIC. Gerne können
Sie mich auch telefonisch unter meiner Durchwahl
0 80 67 / 90 38 10 direkt ansprechen, wenn sich
noch weitere Fragen ergeben sollten.
Mit freundlichen Grüßen
Josef Kirschbaum
Dipl.-Ing. Udo Ohm, http://www.u-ohm.de/ mailto:OHM@BBS4.de
<mailto:OHM@BBS4.de>
Alte Aue 31
30926 Seelze
Tel u. Fax: 0511 40 93 30 Hallo Udo Ohm!
"Udo Ohm" am 16.03.03 / 13:16 (Sonntag):
> kann mir jemand sagen, wie ich meine Turbo-Basic-(Borland)-exe-
> Dateien dekompilieren kann?
Ich weiß von keinem Dekompiler für Turbo-Basic. Möglicherweise hilft
Dir eine Anfrage in einem Forum auf <www.powerbas.de> weiter.
<powerbas.de> ist die kürzlich eröffnete offizielle deutschsprachige
Web-Site zu PowerBASIC und Bob Zales PowerBASIC ist der Nachfolger
von Borlands TurboBASIC.
Gruss elek Hallo,
kann mir jemand sagen, wie ich meine Turbo-Basic-(Borland)-exe-Dateien
dekompilieren kann? Mein Quellcode ist futsch.
Mit freundlichen Grüßen
Dipl.-Ing. Udo Ohm, http://www.u-ohm.de/ mailto:OHM@BBS4.de
<mailto:OHM@BBS4.de>
Alte Aue 31
30926 Seelze
Tel u. Fax: 0511 40 93 30 _________
Hye Kronn,
> Ich behaupte nicht, dass PowerBASIC tot ist. Aber das M$ einen
> kostenlosen Compiler inkl. deutschsprachiger Hilfen dafür zum Download
> anbietet, ist doch eher als Scherz gemeint.
DOS ist tot, das ist was M$ will.
QuickBasic kostet real money. PowerBasic auch, aber
PowerBasic bietet mit FirstBasic seine Version 2.01 zum
Ausprobieren an. Ohne Meckerbildschirm der IDE beim Start
gibts keine Einschränkung, um lauffähige .Exe damit zu erzeugen.
Völlig ausreichend für alle schnellen DOS-Tools.
Kann sogar BCD-Umrechnung für einen EURO-Rechner.
Nur die umfangreiche online-Hilfe ist auf Englisch.
Beispiel falls man das Programm Rechner.Bas tauft:
rechner 200
200.00 Betrag
102.26 EUR
391.17 DM
Wenn man also "Betrag" als EURO betrachtet, kommt der
DM-Betrag raus, wenn man ihn als DM betrachtet kommt
EUR raus.
Klappt auch für Beträge in Höhe des BRD-Bruttozialprodukts.
--------------------------------zip-----------------------------------
'Freeware (c) 2001 Joachim Merkel J.Merkel@Tbx.berlinet.de
'Außer daß das Programm Speicherplatz verbraucht wird für
'zweckentsprechendem oder zweckwidrigen Einsatz für
'nichts weiteres eine Gewährleistung übernommen.
cls
liRand% = 8 '| linke Randeinstellung zum Trennzeichen
SP$ = " "
c$ = COMMAND$
'c$ = "1.15"
IF c$ = "" THEN
c$ = "1"
EUR$ = " 1 EUR = 1.95583 DM"
DM$ = " 1 DM = 0.51129 EUR"
OPEN "CONS:" FOR OUTPUT AS #File1
PRINT #File1, EUR$
PRINT #File1, DM$
PRINT #FILE1, ""
CLOSE File1
END IF
c$ = REMOVE$ (c$, ANY SP$)
Komma$ = "," : Punkt$ = "."
REPLACE ANY Komma$ WITH Punkt$ IN c$
a@@ = VAL(c$)
a$ = STR$(a@@)
al$ = LEFT$(a$, 2)
IF LEFT$(al$, 1) <> "-" THEN
IF RIGHT$(al$, 1) = "." THEN a$ = "0" + a$
ELSE
IF RIGHT$(al$, 1) = "." THEN a$ = LEFT$(a$, 1) + "0" + RIGHT$(a$, LEN(a$)-1)
END IF
a$ = REMOVE$ (a$, ANY SP$)
ar$ = RIGHT$(a$, 2)
IF LEFT$(ar$, 1) = "." THEN a$ = a$ + "0"
'DM$ = " 1.00 DM = 0.51129 EUR"
b@ = a@@ * 195583 /100000 ' konvertiert DEFBCD nach DEFFIX
b$ = STR$(b@)
bl$ = LEFT$(b$, 2)
IF LEFT$(bl$, 1) <> "-" THEN
IF RIGHT$(bl$, 1) = "." THEN b$ = "0" + b$
ELSE
IF RIGHT$(bl$, 1) = "." THEN b$ = LEFT$(b$, 1) + "0" + RIGHT$(b$, LEN(b$)-1)
END IF
b$ = REMOVE$ (b$, ANY SP$)
br$ = RIGHT$(b$, 2)
IF LEFT$(br$, 1) = "." THEN b$ = b$ + "0"
'EUR$ = " 1.00 EUR = 1.95583 DM"
IF a@@ >= 10 THEN
c@ = a@@ * 51129 / 100000 ' konvertiert DEFBCD nach DEFFIX
ELSE ' Umrechnungsfaktor für c@ < 1 aendern
c@ = a@@ * 0.51129 ' konvertiert DEFBCD nach DEFFIX
END IF
c$ = STR$(c@)
cl$ = LEFT$(c$, 2)
IF LEFT$(cl$, 1) <> "-" THEN
IF RIGHT$(cl$, 1) = "." THEN c$ = "0" + c$
ELSE
IF RIGHT$(cl$, 1) = "." THEN c$ = LEFT$(c$, 1) + "0" + RIGHT$(c$, LEN(c$)-1)
END IF
c$ = REMOVE$ (c$, ANY SP$)
cr$ = RIGHT$(c$, 2)
IF LEFT$(cr$, 1) = "." THEN c$ = c$ + "0"
IF INSTR(a$, ".") = 0 THEN a$ = a$ + ".00"
IF INSTR(b$, ".") = 0 THEN b$ = b$ + ".00"
IF INSTR(c$, ".") = 0 THEN c$ = c$ + ".00"
txt1$= a$ + " Betrag "
txt2$= c$ + " EUR "
txt3$= b$ + " DM "
Lentxt3% = LEN(txt3$)
Lenmax% = Lentxt3%
Trennz% = INSTR(txt3$, ".")
'| Randeinstellung
IF Trennz% <= liRand% THEN
Lenmax% = Lenmax% + liRand% - Trennz%
ELSEIF Trennz% > liRand% THEN
Lenmax% = Trennz% + 22
END IF
xx% = LEN(txt1$)
WHILE xx% < Lenmax%
txt1$ = " " + txt1$
xx% = LEN(txt1$)
WEND
xx% = LEN(txt2$)
WHILE xx% < Lenmax%
txt2$ = " " + txt2$
xx% = LEN(txt2$)
LOOP
xx% = LEN(txt3$)
WHILE xx% < Lenmax%
txt3$ = " " + txt3$
xx% = LEN(txt3$)
WEND
OPEN "CONS:" FOR OUTPUT AS #File1
PRINT #File1, txt1$
PRINT #File1, txt2$
PRINT #File1, txt3$
CLOSE File1
END
--------------------------------zap-----------------------------------
\bye
Frank Hallo Kronn!
> Ich behaupte nicht, dass PowerBASIC tot ist.
Schon klar, habe ich auch als Scherz verstanden.
Ich wollte nur mal ein paar Infos zur aktuellen Lage von PowerBASIC
beisteuern. Anscheinend hat PowerBASIC inzwischen einen Stammkunden-
kreis, der groß genug ist, um einträglich zu sein bzw. vernünftige
Investitionen vorzunehmen. Jedenfalls hat Bob Zale, der Chef von
PowerBASIC Inc. in der letzten PowerBASIC-Gazette (eine teilweise
per E-Mail vertriebene Kundenzeitschrift vom PowerBASIC Inc.)
wirklich mitgeteilt, daß die Firma mit ihren Produkten im letzten
Jahr den größten Erfolg seit ihrem Bestehen gehabt hätte.
Mir gefällt es, daß kleinere Firmen mit guter Qualität sich noch
neben den napoleonischen Konzernen behaupten können. Ich muß
außerdem sagen, daß ich den PowerBASIC-Support von Lance Edmunds
vorbildlich finde und mir vom Support bzw. über die PowerBASIC-Foren
im WWW immer zügig geholfen wurde. (Und immerhin war ich früher
Service-Profi.)
Es ist eben doch ein Unterschied, ob man sich auf einer riesigen
Web-Site dumm und dämlich sucht und dann vielleicht einen Text
findet, der das Problem streift, das man hat, oder ob man von
lebenden Menschen eine passende Antwort auf seine Fragen bekommt.
Telefon-Supporter großer Computerfirmen, die nicht wirklich Ahnung
haben und statt dessen Erklärungen aus einer Support-Datenbank
vorlesen, simulieren IMO oft nur ein verständiges Gespräch.
Gruss elek Hi Elek!
Ich behaupte nicht, dass PowerBASIC tot ist. Aber das M$ einen
kostenlosen Compiler inkl. deutschsprachiger Hilfen dafür zum Download
anbietet, ist doch eher als Scherz gemeint.
Wer lesen, lachen und löschen kann, ist klar im Vorteil...
Kronn Hallo Kronn!
> Toll. Und für PowerBASIC? Okay, Scherz beiseite [...]
Der Scherz ist, daß PowerBASIC Inc. im letzten Jahr drei neue
Programme und zwei Handbücher herausgebracht hat und dieses letzte
Jahr das geschäftlich erfolgreichste der Firma seit ihrem Bestehen
war. PowerBASIC ist daher sogar so "tot", daß gerade eine offizielle
deutschsprachige Site dafür aufgebaut wurde. Und PowerBASIC Inc. muß
seine Kompiler nicht einmal verschenken, es ist schon ein Elend. :)
Gruss elek Hi Sebastian!
> Quickbasic- ich liebe es :-)
Oh ja, ich habe damit auf dem PC angefangen und auch wieder aufgehört zu
programmieren. Ich habe sozusagen meinem Programmierleben auf dem PC
durch QB einen Rahmen verliehen.
Meinen kurzen Abstecher nach C (hello-world, temperatur-umrechung) kann
mir M$ mit Sicherheit genauso verzeihen wie kurze Experimente mit Visual
Basic (seinerzeit noch unter Win3.11). Und jetzt, nachdem ich damit
abgeschlossen habe, passiert folgendes:
> MS hat dafür eine nachträgliches Packet mit deutscher Hilfe und einem
> QB-Compiler zum laufen ausserhalb der QB-Umgebung auf dem Download
> Server.
Toll. Und für PowerBASIC? Okay, Scherz beiseite, hattest du mir nicht
irgendwann schonmal einen QB-Compiler zugeschickt? Oder ist nur die
deutsche Version neu?
Fragt sich ein Loch in den Bauch, der
Kronn Quickbasic- ich liebe es :-)
MS hat dafür eine nachträgliches Packet mit deutscher Hilfe und einem
QB-Compiler zum laufen ausserhalb der QB-Umgebung auf dem Download Server. Hallo Kristina,
Kristina Wetzke am 29.01.03 / 08:30 (Mittwoch):
> könnt ihr mir vielleicht ein Buch oder ein paar Links
> für QuickBASIC empfehlen?
Aus dem Kopf fällt mir <http://www.qbasic.de/> ein alternativ kommst
Du zu den selben Seiten über <http://www.antonis.de/>. Wenn Du
weitere Links brauchst, kann ich mal meine Browser-Favoriten sichten
und Dir noch ein paar WWW-Seiten daraus nennen.
HTH elek Hallo Kristina,
mit QBasic kenne ich mich nicht aus, aber ich denke, Dein Problem läßt sich
mit den üblichen Bordmitteln lösen:
Ein zweidimensionales Array dimensionierst Du z.B. so:
n = 20
DIM Namen$(n,2)
Hier kannst Du jetzt z.B. Schleifen programmieren:
FOR i=0 TO 19
INPUT "Vorname ";Namen$(i,0)
INPUT "Nachname ";Namen$(i,1)
NEXT i
FOR i=0 TO 19
PRINT Namen$(i,1);", ";Namen$(i,0)
NEXT i
Um Deine Datensammlung auseinanderzunehmen (z.B. --1--,--3456789)
würde ich so vorgehen:
a$="--1--,--3456789" ' Dein Datum steht hier
n=1 ' ersten Wert einlesen
flg=0 ' =0: Scanne Ziffer, =1 Skip Ziffer
FOR i=1 TO LEN(a$) ' Schleife über Daten
IF INSTR("0123456789", MID$(a$,i,1)) ' Ziffer gefunden?
IF flg=0 ' Ja: Werden Ziffern gesucht?
IF n=1 ' Ja: Zahl1?
Zahl1=VAL(MID$(a$,i)) ' Ja: String in Zahl1 umwandeln
flg=1 ' ab jetzt Ziffern ueberspringen
ELSE IF n=2 ' Zahl2?
Zahl2=VAL(MID$(a$,i)) ' Ja: String in Zahl2 umwandeln
flg=1 ' ab jetzt Ziffern ueberspringen
ENDIF
ENDIF
ELSE IF flg=1 ' Keine Ziffer: Ist Modus = Skip?
flg=0 ' Ja: Modus = Scanne Ziffer setzen
n=n+1 ' Nächste Zahl
ENDIF
NEXT i
Natürlich ohne Gewähr, das Komma kann stehen, wo es will und für Eingaben
der Form <irgendwas ausser Ziffern>Zahl1<irgendwas ausser Ziffern>Zahl2
müßte es funktionieren.
Viel Erfolg beim Übersetzen in QBasic! Hallo
Ich hab keinen so rechten Plan von QuickBASIC und soll nun auf einmal
ohne
einen Kurs oder so was zu besuchen, das einfach bringen. Bis jetzt hab
ich
mich gut durchgekämpft. Aber jetzt hackt es aber heftig. Und zwar hab
ich
keine Ahnung wie ich ein zweidimensionales Array anlege und meine Werte
an
der richtigen Stelle einfüge.
Ich weiß folgendes, was ich brauch. Ich brauche ein zweidimensionales
Array.
Die Anzahl der Spalten ist fest und liegt bei 2. Die Anzahl der
Variablen
ist variabel und lege ich am Anfang des Programms fest.
Noch was: Ich habe zuerst einen String, der an 5.Stelle ein Komma hat,
dass
ist immer so. Muss ich zuerst nach dem Komma suchen, wenn ich dann den
rechten bzw. linken Teil des Strings in eine Variable des Typs Double
umwandeln will??
Und wie würde ich des machen, wenn des Komma nicht immer an derselben
Stelle
ist?
Hier ist mal ein Auszug von meinem Programm.
OPEN "E:\praxis00.txt" FOR INPUT AS #4
PRINT
PRINT "Daten laden"
FOR k = 1 TO NumberPoints
INPUT #4, Zeichen$ --> Mein eingelesenes Zeichen
ist
z.B.: --1-,--345678
Oder --2-,--875.55
DatenIn(k) = Zeichen$
A = INSTR(1, Zeichen$, ",") --> Muss des rein?
'Datenpunkt
Z1 = VAL(LEFT$(Zeichen$, 4))
'Wert
Z2 = VAL(RIGHT$(Zeichen$, 8))
--> Hier bräuchte ich dann
mein
Array
NEXT k
CLOSE #4
Ich wäre euch sehr dankbar für eure Hilfe.
Danke und Tschau!
Kristina.
P.S.: könnt ihr mir vielleicht ein Buch oder ein paar Links für
QuickBASIC
empfehlen? würd mich auch mal intressieren, was das für ne arbeit sein soll-
such übrigends ein gutes gwbasuchandbuch, da mir meins abhanden kam
an geeess@gmx.de Hallo. :)
Als Binärdatei #13 findet Ihr nun ein Demoprogramm für die von mir kürzlich
hier vorgestellte Funktion inputFileName$().
Dateien in dem ZIP-Archiv:
==========================
- ASK4FILE.BAS : Quellkode des Demoprogramms
- ASK4FILE.EXE : Lauffähiges Demoprogramm (32-Bit)
- ASK4FILE.INC : Inkludedatei mit dem Quellkode der Funktion inputFileName$()
Das Demoprogramm zeigt am Bildschirm an, wie die Funktion in Quellkodes
eingesetzt werden kann, und gibt Gelegenheit das Eingabefeld auszuprobieren.
Gruss elek Durch einen Fehler meinerseits stand ein Beitrag hier doppelt, ich habe einen
davon gelöscht.
elek Hallo BASIC-Programmierer!
Heute findet Ihr hier eine einfache Funktion zur Eingabe eines Dateinamens.
Der Kode ist für PB/CC 3.0 geschrieben, läßt sich aber leicht für PB/DOS
ändern.
Für alle, die diesen Code für einen anderen Kompiler als PB/CC 3.0
abwandeln möchten, führe ich hier ein paar Besonderheiten von PB/CC 3.0 auf:
CURSOR : setzt oder erfragt den Cursorstatus.
COLOR : setzt eine Farbe und setzt bei Angabe eines dritten
Parameters die angegebene Zahl von Stellen auf dem
Bildschirm auf die gewünschten Farbwerte, ohne die
Schreibposition zu ändern oder Zeichen vom Bildschirm
zu löschen.
Iif$() : Zuweisung in Abhängigkeit von einem Wahrheitswert.
Iif$( boolean expression, string_for_true, string_for_false )
Bspw.: "zeile& = Iif&( CursorY = ScreenY, CursorY, CursorY+1 )"
CursorY : PB/CC-Ausdruck für CSRLIN (actual screen line)
CursorX : PB/CC-Ausdruck für POS (actual screen row)
Verify() : Gibt eine 0 zurück, wenn der erste String nur aus den Zeichen
im zweiten String besteht. "Verify( mainstring$, consistsOf$ )"
Verify() kann also mit INSTR() simuliert werden:
"IF INSTR( mainstring$, ANY consitsOf$ ) = 0 THEN"
IsTrue : Antwortet mit -1 (Basics true value), wenn der Wert eines
Ausdrucks ungleich 0 ist, sonst gibt IsTrue 0 zurück.
IsFalse : Antwortet mit -1 (Basics true value), wenn der Wert eines
Ausdrucks gleich 0 ist, sonst gibt IsFalse 0 zurück.
"Locate , XPos" entspricht "LOCATE CSRLIN, XPos"
"Local x As Byte" entspricht "DIM x AS LOCAL BYTE"
"WHILE : WEND" ist eine kopfgesteuerte Schleife in PowerBASIC.
»Input Flush« entspricht »WHILE INKEY$<>"" : WEND« und leert den
Tastaturpbuffer.
----- code start --------------------------------------------------
Function inputFileName$ ( YLin As Byte, XPos As Byte, defaultName As String, max
Len? )
'
' Simple edit field for an input of a file name, it builds an color inverted
' field of maxLen? signs and allows to delete the last character or the
' complete field.
'
' The definition of the variable allowedChars$ should be done in a single
' code line. This code uses 3 code lines because of the maximum text width
' in the mailbox, where it is posted.
Local cursorStatus?, colorStatus?, allowedChars$
Local fgColor As Byte, bgColor As Byte
Dim inptFile As Local String
Dim lastKey As Local String
'which characters should be allowed in the file name:
allowedChars$ = ":\._-#"
allowedChars$ =allowedChars$ + "abcdefghijklmnopqrstuvwxyz"
allowedChars$ =allowedChars$ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
cursorStatus? = Cursor
defaultNameLen? = Len( defaultName )
'get the Color:
Locate YLin, XPos-1
colorStatus? = ScreenAttr(CursorY, CursorX)
fgColor = colorStatus? Mod 16
bgColor = colorStatus? \ 16
Locate YLin, XPos
Color bgColor, fgColor, maxLen? 'invert color for the length of the field
Print defaultName;
Locate , XPos
Cursor On, 100
Input Flush : lastKey$=""
Do 'check if default value is accepted
lastKey$ = InKey$
If lastKey$<>Chr$(13) And lastKey$<>"" Then
'remove default file name:
Locate , XPos : ? Space$(defaultNameLen?);
Locate , XPos
End If
Loop Until lastKey$<>""
Do Until ( lastKey$=Chr$(13) )
If IsFalse Verify( lastKey$, allowedChars$ ) And _
(Len(inptFile$) < maxLen?) Then
inptFile$ = inptFile$ + lastKey$
Print lastKey$;
ElseIf ( lastKey$=Chr$(8) ) Or ( lastKey$=Chr$(0,83) ) Then
inptLen% = Len(inptFile$)
Locate CursorY, XPos : Print Space$(inptLen%);
inptFile$ = IIf$( (IsTrue Asc(lastKey$)) And inptLen%>0, _
Left$(inptFile$,inptLen%-1), "" _
)
Cursor Off
Locate CursorY, XPos : Print inptFile$;
Cursor On
End If
lastKey$ = InKey$
Loop
If inptFile$ = "" Then inptFile$ = defaultName
If IsTrue cursorStatus? Then
Cursor On, cursorStatus?
Else
Cursor Off
End If
Color fgColor, bgColor
inputFileName$ = inptFile$
End Function 'inputFileName$()
----- code end ----------------------------------------------------
OPTIMIERUNGSMÖGLICHKEITEN FÜR PB/CC
Auf die Schleife in folgendem Code-Abschnitt könnte man sich in
PB/CC-Code sparen, wenn man statt InKey$ WaitKey$ benutzt:
Input Flush : lastKey$=""
Do 'check if default value is accepted
lastKey$ = InKey$
If lastKey$<>Chr$(13) And lastKey$<>"" Then
Locate , XPos : ? Space$(defaultNameLen?);
Locate , XPos
End If
Loop Until lastKey$<>""
Noch besser paßt an diese Stelle eine Prüfung, ob das eingegebene Zeichen
zulässig ist:
Input Flush
Do 'get first allowed character:
lastKey$ = WaitKey$
Loop Until ( IsFalse Verify( lastKey$, allowedChars$+Chr$(13)+Chr$(0,83) ) )
If lastKey$<>Chr$(13) Then 'check if default value is accepted
'remove default file name:
Locate , XPos : ? Space$(defaultNameLen?);
Locate , XPos
End If
Viel Spaß und Erfolg beim Kodieren wünscht
Elek Hallo BASIC-Kodierer!
"nacboy" am 11.01.03 in comp.lang.basic.misc
(news: 6384c44.0301111933.5d71ebe2@posting.google.com):
> Could someone help me write a simple qbasic program to read
> three (parallel) arrays into memory. A name array, age
> array, and salary array. Each array with 15+ cells. I want
> the arrays sorted alphabetically after after they are
> loaded and to carry along the correct data from the other
> arrays.
> Then i need an identical program that will sort them from
> oldest to youngest.
> Please help!!!
Der Quellkode mit dem ich geantwortet habe, liegt in der Mailbox als
File #20 der Rubrik BASIC.
elek Hallo Cyrion!
Siehste, da erinnere ich mich doch gleich wieder, was ich gestern abend
vergessen hatte. Wird aber nachgeholt, es _muss_ noch da sein! Hallo "Holgy"!
Schreib doch mal genauer, um was es geht, sonst kann sich doch
niemand etwas darunter vorstellen!
Wie kommerziell ist das Projekt? Was soll erstellt werden?
Und wieso gerade GW-BASIC?
elek Hallo BASIC'ler!
Im Files-Bereich (#19) liegt nun eine kleine Quelltextdatei von David Williams,
in der er zeigt, wie sich die Abnzeige im Screen-Modus 11 um 90 Grad drehen
läßt. Durch einen kurzen Kommentar, den ich eingefügt habe,weise ich darauf
hin, wie das Programm sowohl mit QB als auch mit PB läuft. David Williams
Programm ist für QB kodiert.
elek Suche jemand der sich in GW Basic auskennt und zusammen mit mir ein
Projekt fertigstellt. Allein schaff ich das nicht. ( Ab 18) Hallo Programmierer!
Zur Nutzung der API-Funktionen gab mir - neben einigen Leuten aus
Usenet-Foren - per E-Mail Lance Edmonds vom PowerBASIC Support
dankenswerterweise einige Hinweise, die ich mit seiner Zustimmung
hier übersetzt wiedergebe.
Gruss elek
| Fast alle APIs des Betriebssystems benutzen ASCIIZ-Strings
| anstatt dynamischer Strings. Es ist zwar moeglich normale
| Strings zu benutzen, aber dann muessen sie im Stil von
| ByVal StrPtr(a$) uebergeben werden und darueberhinaus muss
| der Programmierer sicherstellen, dass der benoetigte String-
| Speicherplatz vorher definiert wurde. Zum Beispiel:
|
| a$ = STRING$(%MAX_PATH, $NUL)
| Result& = GetModuleFileName(0&, BYVAL VARPTR(a$), LEN(a$))
| a$ = EXTRACT$(a$, $NUL) ' ungefuellte/unbenutzte Bytes abschneiden
|
| Wie man sieht, ist es im allgemeinen viel einfacher einen
| echten ASCIIZ-String zu benutzen, weil das enthaltene $NUL
| dabei automatisch von PowerBASIC gehandhabt wird; wohingegen
| ein dynamischer String Bytes mit dem Wert $NUL enthalten kann,
| wobei wir diese ausdruecklich entfernen muessten.
|
| Im uebrigen ist zu bemerken, dass ein Programmierer den
| Datentyp von Aufrufparametern sehr selten mit CDwd()
| ausdruecklich aendern muss, da PowerBASIC dies automatisch
| erledigt.
( Origin: mail from PowerBASIC support with the id
3.0.5.32.20021230012642.012f2d68@powerbasic.com ) Hallo BASIC-Programmierer!
Viele Programme benutzen eigene Datendateien in denen Datensätze,
Voreinstellungen oder String-Literale abgelegt sind. Solche Dateien liegen
gewöhnlich im gleichen Verzeichnis wie die Programmdatei. PowerBASIC kann
zwar das aktuelle Verzeichnis ermitteln (CurDir$) und genauso den Wert der
Umgebungsvariablen PATH (Environ$), bietet aber keinen Befehl, mit dem der
Pfad zur Datei des laufenden Programms ermittelt werden kann. Wenn man erst
einmal weiß, wie es geht, ist das aber mit einer der Windows-API-Funktionen
GetCommandLine() oder GetModuleFileName() sehr einfach möglich.
Ich erläutere hier kurz die Anwendung dieser beiden API-Funktionen.
Da Windows selber meines Wissens keine Dokumentation der API-Funktionen
mitbringt, hat man als PowerBASIC-Programmierer nur die Angaben in der mit
PowerBASIC ausgelieferten Datei "Win32Api.inc". Diese Datei enthält auch
die Deklarationen der beiden hier infragesteheden API-Funktionen (Achtung:
In "Win32Api.inc" ist das jeweils eine Zeile!):
Declare Function GetCommandLine Lib "KERNEL32.DLL" Alias "GetCommandLineA"
() As Dword
Declare Function GetModuleFileName Lib "KERNEL32.DLL" Alias
"GetModuleFileNameA" (ByVal hModule As Dword, lpFileName As Asciiz, ByVal
nSize As Dword) As Dword
GetCommandLine gibt demnach einen DWORD-Wert zurück. Man kann sich denken,
daß es ein Zeiger auf einen String ist. Die Auswertung gelingt, wenn man
keinen dynamischen, sondern einen nullterminierten String erwartet. In der
Begrifflichkeit von PowerBASIC zeigt GetCommandLine() also auf einen
ASCIIZ-String. Die Abfrage wäre beispielsweise so möglich:
---- Beispiel-Kode fuer PB/CC 3.0 -----------------------------
#Compile Con
#Include "Win32api.inc"
Function PbMain() As Long
Dim n As Asciiz Pointer
n = GetCommandLine()
? @n : WaitKey$
End Function
---- Ende des Beispiel-Kodes ----------------------------------
(Das @ vor dem n ist das Dereferenzierungszeichen von PowerBASIC,
entspricht also dem Sternchen * in C-Kode. Dadurch wird über den DWORD-Wert
in der Pointer-Variablen n auf den Inhalt zugegriffen, auf welchen dieser
DWORD-Wert verweist.)
Die Ausgabe dieses Progrämmchens auf meinem System ist
"C:\PBCC30\source\test\testGetCommandLine.exe"
Und zwar inklusive der Anführungszeichen. Will man das auswerten, muß man
also das führende und folgende Anführungszeichen entfernen. Außerdem
unterscheidet sich die Rückgabe von GetCommandLine() von dem, was
GetModuleFileName() liefert, dadurch daß GetCommandLine() auch alle
Aufrufparameter, also die komplette Kommandozeile zurückgibt. Deswegen ist
es zur Ermittlung des Pfades zur Datei des laufenden Programms einfacher
GetModuleFileName() zu benutzen.
Wie die Deklaration von GetModuleFileName(), die ich schon weiter oben
wiedergegeben habe, zeigt, hat diese API-Funktion eine Aufrufschnittstelle
aus DWORD, ASCIIZ STRING und DWORD:
Declare Function GetModuleFileName Lib "KERNEL32.DLL" Alias
"GetModuleFileNameA" (ByVal hModule As Dword, lpFileName As Asciiz, ByVal
nSize As Dword) As Dword
Dem trage ich in der Funktion GetModuleFilePath() Rechnung, mit der
PowerBASIC-Programmierer in jedem Programm für PB/CC oder PB/Win den Pfad
zur Datei des laufenden Programms ermitteln können und die der heutige
"nützliche Programmschnipsel" für PowerBASIC-Programmierer ist:
---- Beispiel-Kode fuer PB/CC 3.0 -----------------------------
#Compile Con
#Include "Win32api.inc"
Declare Function GetModuleFilePath$
Function PbMain() As Long
Dim ModuleFilePath As Global Asciiz*%MAX_PATH
? GetModuleFilePath$ : WaitKey$
End Function
Function GetModuleFilePath$ Private
Call GetModuleFileName( CDwd(&H0), ModuleFilePath, CDwd(%MAX_PATH) )
name2Cut$ = Parse$( ModuleFilePath, "\", ParseCount(ModuleFilePath, "\") )
Function = RTrim$( ModuleFilePath, name2Cut$ )
End Function
---- Ende des Beispiel-Kodes ----------------------------------
(Für PB/DOS 3.2 gibt es in der kommerziellen Bibliothek PowerTOOLS I von
Dirk Hilger, erhältlich bei Kirschbaum Software, eine Funktion exedir$(),
die ebenfalls den Pfad zur Datei usw. usf. liefert.)
Viel Spaß und Erfolg beim Kodieren wünscht
Elek Hallo!
Der unten wiedergegebene Kode kann als Include-Datei für PBCC 3.0
oder PowerBASIC for Windows 7 benutzt werden. Damit kann mit einer
einfachen IF-Anweisung geprüft werden, ob auf eine Datei zugegriffen
werden kann. Die Funktion dient also dazu diese Überprüfung
jederzeit mit einer einfachen Anweisung formulieren zu können
anstatt an jeder Stelle, an welcher eine Datei geöffnet werden soll,
umfänglichen Kode zum Abfangen von Zugriffsfehlern zu integrieren.
Da es sich gewiss nicht um meinen größten Geniestreich handelt, ich
einige benannte Konstanten benutzt und den Kode kommentiert habe,
dürfte er leicht zu verstehen sein. Trotzdem bin ich für Fragen und
Diskussionen offen.
------- fileOk.inc ----------------------------------
#If Not %Def( %TRUE )
%TRUE = -1
#EndIf
#If Not %Def( %FALSE )
%FALSE = 0
#EndIf
#If Not %Def(%READONLY)
%READONLY = 1
#EndIf
%NOT_READY = 0
%READY = -1
Function fileok%( filespec$ )
'
' Wenn eine Datei vorhanden, zugriffsbereit und zum Schreiben
' freigegeben ist, gibt die Funktion %TRUE (-1) zurueck,
' sonst %FALSE (0).
'
Local answer%, fileAccess%
If ( Len( Dir$( filespec$ ) ) <> 0 ) Then
If (GetAttr(filespec$) And 1&) <> %READONLY Then
fileAccess% = %READY 'Defaultwert gesetzt
On Error GoTo accessError
fileNum& = FreeFile
Open filespec$ For Binary Access Read Write Lock Read Write As fileNum&
Close fileNum&
errorResume:
On Error GoTo 0
If fileAccess% Then
answer% = %TRUE
End If
End If
Else
answer% = %FALSE
End If
Function = answer%
Exit Function
accessError:
fileAccess% = %NOT_READY
Resume errorResume
End Function
------- Dateiende -----------------------------------
Eine Routine, mit der man ohne viel Aufwand abfragen kann, ob eine Datei
existiert, findet sich schon in den PowerBASIC-Handbüchern:
------- Kode-Anfang ---------------------------------
FUNCTION Exist( file$ ) AS LONG
LOCAL Dummy&
Dummy& = GetAttr( file$ )
FUNCTION = (ErrClear = 0)
END FUNCTION 'Exist&()
------- Kode-Ende -----------------------------------
Allgemein möchte ich darauf hinweisen, daß zu älteren hier als
"praktische Programmschnipsel" vorgestellten Routinen - etwa zu den
unter http://www.chatnoir.de/foren/w3.basic.htm#94917 vorgestellten -
teilweise bessere neuere Versionen existieren. Da die Mailbox ein
Editieren durch Pollen hochgeladener Beiträge aus irgendwelchen
fundamentalistischen Gründen, die ich weder diskutieren noch verstehen,
ja nicht einmal kritisieren möchte, nicht zuläßt, habe ich darauf
verzichtet, irgendwelche Verbesserungen hier zu posten. Wer Interesse an
der aktuellsten, vielleicht verbesserten Fassung einer Routine hat,
braucht mich nur danach zu fragen.
Viel Spaß und Erfolg beim Kodieren wünscht
Elek Gerade eben kam eine Mail von Kirschbaum Software (um 19:00 Uhr
abgeschickt), daß es nun ein offizielles deutschsprachiges Forum zu
PowerBASIC gibt:
http://www.powerbas.de/
Natürlich erfährt man dies hier im BASIC-Forum der CN schneller als
anderswo. :)
elek PB/CC 3.0 Programme in deren Quellkode die Anweisung "#Debug Print"
steht, lassen sich verkleinern, indem man jeden dieser Debugging-
Befehle auskommentiert. Zwar wird der ausführbare Debugging-Code
schon durch den Meta-Befehl "#Tools Off" deaktiviert; der Compiler
speichert dann aber trotzdem die Literale, welche mit "#Debug Print"
ausgegeben würden im Kompilat. Sind die "#Debug Print"-Anweisungen
auskommentiert, geschieht das selbstverständlich nicht.
elek Hallo Leute!
An den Quellkode bin ich inzwischen rangekommen udn habe inzwischen
GWBASIC.EXE.
GW-BASIC speichert die Sourcen binär ab, mit GWBASIC.EXE läßt sich
das Zeug öffnen und dann auch als ASCII-Datei auf die HD schreiben.
Gruss elek Falls jemand eine digitalisierte Kurzreferenz (Befehle und Syntax)
zu GW-BASIC hat, bitte ich das in die Box hochzuladen oder mir per
E-Mail zu schicken.
Gruss elek Hallo!
Hat jemand einen Dekompiler für GW-BASIC oder weiß, wo ich
derartiges herbekomme?
Konkret liegt mir der Bytecode eines Programmes in GW-BASIC 3.11 vor
und ich will daraus automatisch einen Quellcode ableiten lassen.
Gruss Elek Hallo Helmut Schabetsberger,
Du meintest am 28.11.02 um 18:36 Uhr:
> [Wer kann einige Zeilen in ein 15 Jahre altes BASIC-Programm
> einbauen?]
Kommt drauf an, worum genau es geht. Zum Beispiel auf Umfang und Art
des Programms und darauf, was ergaenzt werden muss.
Was macht dieses Programm und was soll es nach der Aenderung
koennen?
Wenn es sich in einem gewissen Rahmen haelt, helfe ich. Muß ich aber
erst mehr drüber erfahren. Ich muß wissen, worum es geht und den
Sourcecode sehen.
elek
----
BTW: Ich wundere mich, dass der Gute mit einem 15 Jahre alten
Basic-Programm ein paar Euro verdienen kann. hi freunde
habe ein problem: ich habe ein 15 jahre altes basic-programm, das ich
einem jungen verwandten schenken möchte, der im rollstuhl ist und der
einige euro verdienen möchte, wer kann ihm helfen und einige zeilen
einbauen, damit es funktioniert? Hallo BASIC-Kodierer!
Als Textdatei #18 der Rubrik BASIC findet ihr nun online in der Mailbox einen
Quelltext für PB/CC 3.0 der eine Auswertungsroutine für eine sich während der
Programmlaufzeit dynamisch ändernde Anzahl von Regeln demonstriert. Die
ausführbare Datei für 32-Bit-Windows liegt als Binärdatei #12 bereit.
Für PowerBASIC-Programmierer (PB/DOS 3.2, 3.5, PB/CC neuere) demonstriert das
Programm u. a. eine Anwendung von "CALL DWORD", womit eine Funktion über einen
Pointer aufgerufen wird.
Das Programm ist eine Lösung zu einer Programmierübung, die Henry Ledgard und
Andrew Singer in ihrem BASIC-Lehrbuch "BASIC auf der Spur" darstellen. In zwei
Kapitel wird in diesem unterhaltsamen Lehrbüchlein ein rätselhafter Mordfall
zum Anlass genommen, ein kleines Programm vorzustellen, das die vorliegenden
Hinweise auswertet und den Mörder ermittelt. Ledgard und Singer führen dabei
in unverdächtigem Plauderton und doch wohlbedacht Grundlagen des
Programmierens vor. In diesem Buch habe ich kürzlich wieder geschmökert und
dabei kam mir in den Sinn, daß der vorgestellte Algorithmus eigentlich kein
"intelligentes Programm" ist. Also habe ich heute eine "intelligente" Lösung
kodiert, das Ding, das ihr nun in der Mailbox herunterladen könnt.
DER QUELLTEXT (File #18) ENTHÄLT EINEN AUSFÜHRLICHEN KOMMENTARKOPF, DER ALLEIN
AUSREICHT, DIE AUFGABE NACHZUVOLLZIEHEN. Trotzdem empfehle ich Anfängern, sich
das Buch antiquarisch oder aus einer Öffentlichen Bibliothek zu besorgen.
DIE ART DES PROBLEMS
Die Aufgabe, welche zu lösen ist, ähnelt der, eine Tür zu öffnen, die mit
mehreren Schlössern bewehrt ist. Du mußt Dir vorstellen, Du hättest 9
Schlüssel und stündest vor einer Tür mit neun Schlössern. Nach und nach würde
man Schlüssel ausprobieren, um festzustellen, welcher Schlüssel zu welchem
Schloß paßt. Es geht darum, eine Lösung zu kodieren, welche ein solches
Problem klug löst.
Diese Analogie taucht nicht in dem erwähnten Buch auf, aber wer sich die
konkrete Aufgabe in meinem Kommentar am Anfang des Quelltextes durchliest, wird
durch diesen Vergleich vielleicht noch leichter verstehen, worum es geht.
Mein Ziel war ein Programm, das nicht der Aufgabe unangemessener vorgeht, als
ein Mensch vorgehen würde, der die gleiche Aufgabe anstatt des Computers zu
lösen hätte, mit anderen Worten ein "intelligentes Programm".
Gruss elec Hallo!
Ich habe für die Rubrik BASIC zusätzliche Pseudos eingetragen, so daß sie
auch über kurze Pseudos via E-Mail beschickt werden kann. Die Rubrik hat jetzt
folgende Namen:
w3.basic
w3.Bas
w3.PB
w3.VB
BASIC
PB
PowerBASIC
VB
Alle mit "w3." beginnenden eignen sich dazu, einen Beitrag als E-Mail übers
Internet an die Mailbox zu schicken.
Gruss elec Hallo BASIC-Programmierer!
Heute stelle ich eine Funktion für PB/CC und PB/Win vor, mit der
sich ein, genau ein assoziatives Array erzeugen und nutzen läßt.
Ein assoziatives Array ist eine Liste deren Inhalte über
Schlüsselwörter, statt über Indexzahlen, angesprochen werden.
Perl wird ein assiziatives Arrays "hash" genannt und diese
Datenstruktur ist in verschiedenen Sprachen, so auch in PHP von
vornherein vorhanden.
Die hier vorgestellte Funktion ermöglich einen sehr einfachen
Zugriff, d. h. mit minimalem Schreibaufwand lassen sich
Schlüsselwort-Wert-Paare erzeugen und Werte später lesen. Ein
Löschen von Schlüsselwerten habe ich nicht vorgesehen, das läßt
sich aber einbauen.
------ code begin --------------------------------------------------
TYPE hashdata
key AS STRING*25
value AS STRING*50
END TYPE
DECLARE FUNCTION hash$ (STRING, OPT BYVAL STRING)
FUNCTION hash$ ( key$, OPTIONAL BYVAL value$ )
STATIC size&
LOCAL answer$
LOCAL done AS BYTE
key$ = LCASE$( key$ )
IF ( size& = 0 ) THEN DIM assArray(0) AS STATIC hashdata
FOR i&=0 TO size& 'accessing the value of an existing key
IF ( RTRIM$( assArray(i&).key ) = key$ ) THEN
IF value$ <> "" THEN 'set
assArray(i&).value = value$
answer$ = value$
ELSE 'get
answer$ = RTRIM$( assArray(i&).value )
END IF
done = 1
EXIT FOR
END IF
NEXT i&
IF ISFALSE(done) THEN 'add a new key and value
INCR size&
REDIM PRESERVE assArray(size&) AS STATIC hashdata
assArray( size& ).key = key$
assArray( size& ).value = value$
answer$ = value$
END IF
Hash$ = answer$
END FUNCTION
------ code end ----------------------------------------------------
Dieser Kode kann einfach als gesonderte Datei "hash.inc"
abgespeichert und am Beginn von Programmen mit "#INCLUDE hash.inc"
übernommen werden.
Als Textdatei #17 der Rubrik BASIC findet sich der Quellkode zu
einem Programm, das die Anwendung dieser Hash-Funktion demonstriert.
Binärdatei #11 ist die lauffähige Demo, dieses Demoprogramm zeigt
die Befehle an, mit denen der Hash benutzt wird und kommentiert (in
Englisch) was sie bewirken.
Viel Spaß und Erfolg beim Kodieren wünscht
Elek Hallo!
Ein assoziatives Array ist eine Liste, deren Felder nicht über einen
Zahlenindex, sondern über Schlüsselwörter angesprochen werden.
Folgende Uploads in die Mailbox:
Text-File #16: Quelltext eines Demoprogramms, in dem ein assoziatives Array
mit PowerBASIC implementiert ist.
Binär-File #11: Das lauffähige Programm zu dem Quelltext.
Das Demoprogramm ist für 32-Bit-Windows kompiliert, und der Quelltext für
PB/CC 3.0 geschrieben. Ich habe den Quelltext jedoch so kommentiert, dass er
leicht nach PB 3.5 (DOS) portiert werden kann. (Nur wenige Änderungen sind
nötig.) Für ältere PowerBASIC-Compiler für DOS als die Version 3.5 muß man
eine grundsätzlichere Änderung vornehmen, weil dieses Programm mit dem Befehl
"ReDim Preserve" arbeitet, der erst ab der Version 3.5 verfügbar ist.
Gruss Elek Hallo BASIC-Programmierer!
Daß PowerBASIC keine tote Programmiersprache ist, unterscheidet
diesen BASIC-Dialekt zum Beispiel von QBasic.
Gelegentlich, wenn mir etwas Passendes durch den Kopf geht, schicke
ich eine kurze Mail an PowerBASIC, welche Fähigkeiten ich mir in
kommenden PowerBASIC-Versionen wünsche. Da PowerBASIC Inc. kein
Moloch mit zig Produkten ist, sondern eine überschaubare Firma, für
die der PowerBASIC-Compiler *das* Schlüsselprodukt ist, kommt es der
Firma auf die Qualität ihres Compilers wirklich an und solche Mails
sind nicht vergeblich.
So habe ich auch gestern drei Verbesserungsvorschläge an PowerBASIC
Inc. geschickt und heute die Antwort "Keep it coming!!!" bekommen,
was ich so verstehe, daß die Vorschläge in künftigen PB-Versionen
umgesetzt sein werden.
Ein Vorschlag von mir war, daß in PB die foreach-Kontrollstruktur
eingebaut werde, die mir an PHP und Perl besonders gefällt:
| cls
| ?
| print "members:"
| print "--------"
| ?
| foreach element$ in liste$
| print " "; element$
| next
| ?
foreach ist eine Zählschleife, die über eine Liste, also ein
eindimensionales Array läuft. Das praktische an dieser
Kontrollstruktur ist, daß der Programmmierer nicht ausdrücklich
abfragen muß, wieviele Elemente die Liste hat.
Gruss Elek Hallo.
Als Binärdatei #10 steht jetzt ein DOS-Programm zur Verfügung, das eine kurze
deutsche Erläuterung zu einer beliebigen Laufzeitfehlernummer von PB/DOS in
einem Fenster anzeigt. Das Programm steht quasi unter GPL, d. h. ich gestatte
die kostenlose nicht-kommerzielle Nutzung und Verbreitung dieses Tools.
Wer Schwierigkeiten hat, sich in die Mailbox "Chat Noir" einzuwählen und sich
die Binärdatei #10 herunterzuladen, kann sich bei mir oder hier melden, dann
schicke ich die Datei via E-Mail.
Das Tool heißt *deutErr* und erklärt sich selber, wenn es ohne Parameter
aufgerufen wird.
bye elek Hi!
Binärdatei #9: Zwei gezippte Quellkodes für PB 3.x (DOS). die Routinen liefern
deutsche bzw. englische Meldungstexte zu Laufzeitfehlern (Fehlernummernbereich
0-260). Außerdem kann der Programmierer damit eigene Laufzeitfehler
definieren.
Feedback von Anwendern dieser Quellkodes ist erwünscht.
Bye Elek Hallo!
Als Textdatei #15 ist nun in der Mailbox eine Include-Datei für
PB/CC 3.0 abrufbar, die deutsche Meldungstexte für Laufzeitfehler
bereitstellt und mit der eigene Laufzeitfehlermeldungen definiert
werden können.
Der Kode ist auch mit PowerBASIC for Windows lauffähig und müßte nur
an sehr wenigen Stellen geringfügig geändert werden, damit er mit
PowerBASIC für DOS benutzt werden könnte.
Gruss Elek Hallo!
Schullians RInstr-Implementierung arbeitet auf oberster Ebene
genauso wie die von Cyrion, d. h. mit einer rückwärst laufenden
Zählschleife.
"S_ptr" und "T_ptr" im folgenden Quellkode-Auszug sind Zeiger
(Pointer); "T_ptr" verweist auf die zu durchsuchende Zeichenkette,
"S_ptr" auf die zu suchende.
-------------------------------------------------------------------
FUNCTION [...]
[...]
FOR X% = Tlen% TO 0 STEP -1 ' start search
IF @S_ptr[0] <> @T_ptr[X%] THEN ITERATE ' if 1st Srch$ not a match
IF Slen% = 0 THEN EXIT FOR ' if only 1 char search
Z% = X% ' offset in Txt$
FOR Y% = 1 TO Slen% ' confirm all chars
INCR Z% ' next pos in Txt$
IF @S_ptr[Y%] <> @T_ptr[Z%] THEN EXIT FOR ' not equal - exit early
NEXT '
IF Y% > Slen% THEN EXIT FOR ' WE HAVE A WINNER!
NEXT '
FUNCTION = ( X% + 1 ) ' RETURN position
END FUNCTION
-------------------------------------------------------------------
Inzwischen habe ich auch einen kleinen Test gemacht, um
festzustellen, wie schnell Schullians RInstr-Funktion ist. Demnach
gilt für PowerBASIC 3.5, daß meine Methode aufgrund der aufwendigen
StrReverse() am langsamsten ist, Cyrions Methode mit einer rückwärts
laufenden Zählschleife ist um einiges schneller - und Schullians ist
am schnellsten.
Bei dem Test muß jede der drei Implementierungen der Funktion
RInstr() 5000 mal einen längeren String und 8330 mal einen kürzeren
String überprüfen. Die 8330 Untersuchungen kürzerer Strings
erledigte die RInstr-Implementierung von Schullian in weniger als
einer Sekunde, so daß mein einfaches Testprogramm die benötigte Zeit
nicht mehr messen konnte.
Gruss Elek Hallo!
Als TextFile #14 habe ich hier eine RInstr-Version von Don Schullian
für PowerBASIC 3.5 abgelegt. Der Code stammt aus dem Archiv von
PowerBASIC Inc.
Diese RInstr-Implementierung unterscheidet sich von den beiden
bisher hier diskutierten von Cyrion bzw. mir, weil Schullians
RInstr() nicht nur nach einzelnen Zeichen suchen kann. Damit wäre
also z. B. das Folgende möglich:
main$ = "C:\pb35\source\Rinstr.bas"
searched$ = ".bas"
main$ = LCase$( main$ )
signPos% = RInstr( 0, main$, searched$ )
Schullians RInstr-Implementierung benutzt Pointer, weshalb sie für
andere BASIC-Compiler als PowerBASIC nicht unverändert benutzt
werden kann.
Gruss Elek Hallo,
kennt jemand einen Weg in BASIC, vorzugsweise in PowerBASIC Speicher
für Datenelemente dynamisch zu allozieren, ohne daß dafür *ReDim*
mißbraucht wird. Es geht mir nicht darum einen String dynamisch zu
allozieren, sondern eine unvorhersehbar und beliebig große Zahl von
Datenelementen. Für die Allozierung eines speziellen Datenelements
benutzt man ja in BASIC einen speziellen Variablennamen, auch
unterstützt BASIC meines Wissens keinen generierten Variablennamen.
Es gibt Sprachen, in denen man einen Variablennamen oder einen
Befehl über eine Variable generieren kann, dazu dient dann einen
spezielle Funktion, die angibt, daß der Übergabewert der Funktion
als Befehl zu verstehen ist. Damit wäre es möglich immer wieder neue
Datenelemente mit neuem Namen zu erzeugen. Etwas so:
i++
eval( "DIM string" + Str$(i) + "AS STRING" )
Meines Wissens ist sowas in BASIC, zumindest in PowerBASIC völlig
unmöglich.
Also kennt jemand einen Weg in BASIC dynamisch beliebig oft Speicher
für ein neues Datenelement zu allozieren, ohne "ReDim Preserve" zu
benutzen?
Gruss Elec Hallo BASIC-Programmierer!
Vergleicht ein BASIC-Programmierer Strings, mag er sich manchmal
vorkommen wie in einem Trainings-Camp für LISP-Codierer: Zwei Klammern
kommen selten allein. Oder: Irgendwo braucht es garantiert noch eine
weitere Klammer.
Dagegen liefere ich hier vier Gegenmittel, die erste Funktion "equals%()"
implementiert eine Funktion aus den PowerTOOLS von Dirk Hilger mit PB-
Bordmitteln, die drei anderen Funktionen sind effizientere Abarten
der Funktion equals%() für speziellere Fälle.
Viel Spaß und Erfolg beim Kodieren wünscht
Elek
FUNCTION equals%( t1$, t2$, start&, length&, caseFlag? )
'
' Vergleicht eine bestimmte Anzahl Zeichen zweier Strings
' ab einer bestimmten Position.
'
' (Imitiert die gleichnamige Assembler-Funktion aus den PowerTOOLS)
'
' t1$ und t2$ sind die zu vergleichenden Strings. start%
' beinhaltet die Anfangsposition, ab der der Vergleich
' stattfinden soll, length& die Anzahl der zu vergleichenden
' Zeichen.
'
' Der Parameter caseFlag? ist logisch wahr, wenn zwischen Gross-
' und Kleinschreibung nicht unterschieden werden soll.
'
' Liefert als Antwort
'
' 1 wenn beide Stringabschnitte gleich sind
' 0 wenn beide Abschnitte nicht gleich sind
'
caseFlag? = MIN&( caseFlag?, 1 )
IF caseFlag? = 1 THEN
t1$ = UCASE$(t1$)
t2$ = UCASE$(t2$)
END IF
IF MID$( t1$, start&, length& ) = MID$( t2$, start&, length& ) THEN
equals% = 1
ELSE
equals% = 0
END IF
END FUNCTION 'equals%()
FUNCTION ciEquals%( t1$, t2$, start&, length& )
'
' Case-insensitiver Stringvergleich
'
' Erlaeuterung: siehe Funktion equals%()
'
IF MID$( UCASE$(t1$), start&, length& ) = _
MID$( UCASE$(t2$), start&, length& ) THEN _
ciEquals% = 1
ELSE
ciEquals% = 0
END IF
END FUNCTION 'ciEquals%()
FUNCTION LEquals%( t1$, t2$, length& )
'
' Case-insensitiver Stringvergleich der length& linken Zeichen.
'
' Gibt 1 zurueck, wenn die length& ersten Zeichen der beiden
' Strings t1$ und t2$ abgesehen von Gross- und Kleinschreibung
' gleich sind; sonst 0.
'
IF LEFT$( UCASE$(t1$), length& ) = LEFT$( UCASE$(t2$), length& ) THEN
LEquals% = 1
ELSE
LEquals% = 0
END IF
END FUNCTION 'LEquals%()
FUNCTION REquals%( t1$, t2$, length& )
'
' Case-insensitiver Stringvergleich der length& rechten Zeichen.
'
' Gibt 1 zurueck, wenn die length& letzten Zeichen der beiden
' Strings t1$ und t2$ abgesehen von Gross- und Kleinschreibung
' gleich sind, sonst 0.
'
IF RIGHT$( UCASE$(t1$), length& ) = RIGHT$( UCASE$(t2$), length& ) THEN
REquals% = 1
ELSE
REquals% = 0
END IF
END FUNCTION 'REquals%() Hi Elek!
> Ich könnte noch einen Weile weiter zu dem Thema schreiben
Das ist mir klar, aber war genau das, was ich wissen wollte.
Weitergehende Infos, Methoden oder Anwendungsbeispiele werden mich wohl
erst interessieren, wenn ich selbst wieder programmiere und dann auf OOP
zurückkommen möchte.
Danke für die Erläuterung.
Wer lesen, lachen und löschen kann, ist klar im Vorteil...
Kronn
Ach ja: Diese Nachricht, Elek, war vom Umfang und der Detailtiefe her
endlich mal eine Punktlandung. Hallo C.-koch,
Deine Argumente sind nicht von der Hand zu weisen, und das Problem
der Thread-Sicherheit ist mir auch schon durch den Kopf gegangen.
Andererseits muß ich realistischerweise anmerken, daß ich das Modul
eigentlich nicht entwicklet hatte, um damit die Menschheit zu
beglücken oder DFUE-Programme zu ergänzen, sondern nur die
Herausforderung angenommen habe, mir für meinen Header-Kürzer selber
eine Fortschrittsanzeige auszudenken und zu implementieren. Da der
Header-Kürzer bisher ein DOS-Programm ist, in das der Unit-Kode zur
Kompilierzeit statisch eingebunden wird, gibt es - im engen Rahmen
des Header-Kürzers - kein Thread-Problem.
Ich gebe aber zu, daß ich daran gedacht habe, das Ding threadsicher
zu machen, sofern ich es im PowerBASIC-Archiv zur Verfügung stelle.
Ich bin trotzdem mit meiner Unit zufrieden, sie tut, was sie tun
sollte und ist für meinen Geschmack recht ordentlich programmiert.
Das wird mich aber nicht davon abhalten, andere Implementierungen
von Fortschrittsanzeigen zu studieren, weil ich etwas daraus zu
lernen hoffe, wie ich auch aus Deinen Hinweisen etwas gelernt habe.
(Dateien, die einfach so während der Verarbeitung wachsen. Tztztz)
Gruss Elek Hallo Kronn!
> Das ist also ein Beispiel für Objektorientierte
> Programmierung?
Ich hatte, in einem früheren Beitrag angedeutet, daß ich diese Unit
aufgrund meiner Kenntisse in objektorientierter Programmierung so
gebaut habe, wie sie gebaut ist:
BASIC #352:
"( Das kommt davon, wenn man sich mit OOP beschäftigt. ;)"
Meine Unit ist ein Beispiel für objektorientiertes Denken beim
Modulentwurf, aber nicht für alle theoretischen Aspekte
objektorientierter Programmierung.
An den Anfang der Quellkodedatei für die "Fortschrittsanzeige" hatte
ich übrigens, bevor auch nur eine Zeile Kode darin stand,
geschrieben:
Entwurfsziele: Im Prinzip geht es in dieser PBU um ein
klassiches Objekt im Sinne der OOP.
[...]
> Dass man den Code in einzelne, autonome Module aufteilt
> [ist objektorientiert]?
Modularisierung ist *ein* wesentliches Merkmal der
objektorientierten Programmierung.
Zu objektorientierter Programmierung gehören u. a. folgende Dinge:
- Modularisierung in Klassen
- Abstraktion
- Datenkapselung
- Vererbung
- Polymorphie
Die modulare Programmierung wird gelegentlich als eine konsequente
Weiterentwicklung der strukturierten Programmierung beschrieben. Und
ich fände es durchaus nicht abwegig, wenn jemand die
objektorientierte Programmierung als eine konsequente
Weiterentwicklung und als eine spezielle Form modularer
Programmierung beschriebe. Ein Objekt in Java ist nichts anderes als
eine spezielle Form von Modul:
Objekte sind Module in denen Daten und diejenigen Funktionen
oder Prozeduren zusammengefaßt sind, welche diese Daten
manipulieren, schreiben oder lesen. Ein zentrales Ziel der
objektorientierten Programmierung ist es, anders als bei
daten- oder funktionsorientierten Entwicklungsmethoden, die
Trennung von Daten und Programm aufzuheben.
Außerdem spricht man in der OOP von "information hiding" und meint
damit, daß ein Objekt nach außen eine Black Box ist, ähnlich wie ein
Radio für den durchschnittlichen Nutzer ein Gerät ist, das ein paar
klar definierte Bedienknöpfe und Anschlußmöglichkeiten hat, aber
dessen Innenleben er nicht kennen muß, um es zu benutzen. In der
objektorientierten Programmierung werden direkte Zugriffe auf
Variablen eines Objekts weitgehend, möglichst sogar völlig
unterbunden, stattdessen wird von außerhalb eines Objekts nur über
spezielle, nur dafür gebaute Funktionen auf die Daten eines Objekts
zugegriffen. Genauso ist das in meiner Unit, Du kannst keine
Variable der Unit direkt setzen oder auch nur lesen, sondern nur
über die Funktionen und Prozeduren, welche für diesen Zweck in die
Unit eingebaut wurden.
Ich könnte noch einen Weile weiter zu dem Thema schreiben, aber ich
fürchte, diese Portion ist schon fast so groß, daß sie Deine
Aufnahmebereitschaft überstrapaziert.
Kannst Du mit der Antwort etwas anfangen?
Oder worum ging es Dir sonst?
bye elek Hallo Elek,
so stolz Du auf Deine Fortschrittsanzeige bist, die Lösung, die bisher
ermittelten Werte (z.B. das Maximum) statisch zu speichern, hat signifikante
Nachteile. Ich weiß das aus eigener Erfahrung, denn sowas hatte ich auch mal
programmiert.
Die Nachteile sind: Wird der Maximalwert während der Anzeige der
Fortschrittsanzeige größer (das ist z.B. möglich, falls jemand sowas für
ZModem nutzen möchte, denn ZModem verkraftet auch Dateien, die sich während
der Übertragung (!) vergrößern (Beispiel: Log-Files), der zweite Nachteil
ist, dass das statische Speichern von Werten nicht Thread-sicher ist, d.h.
mehrere Threads, die gleichzeitig den Code beackern, kommen da miteinander
in Konflikte. Daher ist es eigentlich eine sehr gute Idee, den (bisherigen)
Maximalwert bei jedem Aufruf mitzuübergeben, auch wenn es etwas
umständlicher erscheint und die Laufzeit verlängert. Hi Elek!
Das ist also ein Beispiel für Objektorientierte Programmierung? Dass man
den Code in einzelne, autonome Module aufteilt?
Außerdem bringt es ja vielleicht irgendeinem zukünftigen PB (Progress
Bar)-Programmierer doch etwas, wenn du dein PB (Power Basic) allgemein
zur Verfügung stellst. Trotzdem würde ich deinen alternativen Lösungsweg
veröffentlichen (wenn du damit nicht Geld verdienen willst oder kannst).
Wer lesen, lachen und löschen kann, ist klar im Vorteil...
Kronn Hallo Kronn, Programmierer!
Goldbloom ruft seine "percent bar routine" jedesmal beispielsweise
so auf:
CALL percentbar( count, begin, finish, 23, 1, 72, 1 )
Meine Fortschrittsanzeige "progres3" wird nach einem einmaligen
Initialisierungsaufruf, bei dem 6 Parameter an die
Fortschrittsanzeige übergeben werden, nur noch so aufgerufen:
writeProgress amount??
Warum geht das so einfach? Weil meine Unit quasi weiß, was sie ist.
In einer Einführung in die objektorientierte Programmierung würde
ich schreiben, daß diese Unit ein Spezialist für sich selber ist,
sie ist Spezialist und alleinig zuständig für alle Belange einer
Fortschrittsanzeige von Typ "progres3".
Übrigens räumt sich meine Fortschrittsanzeige auch am Ende nach
einer kleinen Pause automatisch vom Bildschirm weg und stellt den
vorherigen Zustand des Bildschirms wieder her. Denn die Unit weiß,
wie sie sich selber wieder verdünnisieren kann, ihr muß kein anderer
(Code) hinterherräumen.
Mit anderen Worten: Meine Unit ist auch ganz nett, obwohl sie nicht
zu einem neuen Weltwunder avancieren wird. Vielleicht schafft sie es
aber in die Beispielprogramme, die mit der nächsten Version von
PowerBASIC für DOS verbreitet werden. Nutzen würde mir das freilich
nix und danken würde mir dafür auch kaum ein Schwein; also etwas,
was ich absolut nicht verpassen sollte. :->>
bye elek Hallo Kronn!
> Hast du deine (offensichtlich bessere) Version denn schon
> dem Archiv angeboten?
Daran habe ich schon gedacht, aber dazu muß ich mir erst die Zeit
nehmen, das Modul englisch zu kommentieren, sonst kann ich das
gleich sein lassen.
Ich bin mir bei der Zeitmessung inzwischen nicht mehr ganz sicher,
ob sie korrekt war, aber ich habe mir bisher nicht die Mühe gemacht,
das nochmals supergründlich zu überprüfen.
Die Implementierungen unterscheiden sich in ihrem Ansatz und in
vielen Details; z. B. übergibt Goldbloom bei jedem Aufruf der
Fortschrittsanzeige die bisherige Summe, ich übergebe bei jedem
Aufruf nur den neu hinzugekommenen Wert. D. h. meine
Fortschrittsanzeige hat ein eigenes Gedächtnis, und speichert alle
für die Fortschrittsanzeige relevanten Daten (Position, Breite,
bisher dargestellte Prozente und anderes) statisch in einer von
außen nicht direkt aufrufbaren Prozedur. ( Das kommt davon, wenn man
sich mit OOP beschäftigt. ;)
Gruß Elek Hi Elek!
> Irgendwas muß ich also richtig gemacht haben. :)
Hast du deine (offensichtlich bessere) Version denn schon dem Archiv
angeboten? Damit deine Bemühungen vielleicht auch außerhalb der CN
Anerkennung finden, meine ich.
Wer lesen, lachen und löschen kann, ist klar im Vorteil...
Kronn
Ach ja: Herzlichen Glückwunsch. Hallo!
Ich habe mir ein paar Quellkodes aus dem PowerBASIC-Archiv besorgt,
u. a. eine "progress bar" von James Goldbloom. Ich habe eigentlich
vermutet, sie sei schneller als meine aufwendige Variante.
DenksTe! Die Zeitmessung nach einer Zählschleife ergab, daß meine
Fortschrittsanzeige mehr als doppelt so schnell ist.
Irgendwas muß ich also richtig gemacht haben. :)
Gruss Elek Hallo!
In PowerBASIC für DOS wird die Schreibmarke umständlich über den
dritten Parameter von LOCATE ein bzw. ausgeschaltet. In den neueren
PowerBASIC-Dialekten für Windows gibt es stattdessen den Befehl
"CURSOR on|off".
Im Prinzip das Gleiche ist in PB für DOS mit geringem Aufwand zu
erreichen:
1. Eine einfache Quelltextdatei folgenden Inhalts in das Include-
Verzeichnis schreiben:
----- Beginn der Include-Datei "cursor.inc" -----------
%VISIBLE = 1
%INVISIBLE = 0
SUB cursor ( status% ) PUBLIC
'
' Cursor-Anzeige ein- oder ausschalten
'
LOCATE csrlin, pos, status%
END SUB
----- Ende der Include-Datei --------------------------
2. In jedes Programm, das den neuen Befehl nutzen soll, schreibt
man vor das eigentliche Hauptprogramm den Compiler-Befehl,
welcher diesen Programmschnipsel in die Kompilation einbezieht:
$INCLUDE "cursor.inc"
3. Im Programm werden nun die folgenden Befehle verstanden:
CURSOR %VISISIBLE
CURSOR %INVISIBLE
(Allerdings muß darauf geachtet werden, daß es noch keine Integer-
Konstanten gleichen Namens gibt.)
Einfach, aber praktisch. ;)
Viel Spaß und Erfolg beim Kodieren wünscht
Elek Hallo BASIC-Programmierer,
gestern bin ich auf eine Site gekommen, die einiges für Qbasic-Freunde
bereithält, aber auch einen Text zu PowerBASIC. Die beste einführende
Produktbeschreibung von PowerBASIC im deutschsprachigen WWW, an die
ich mich im Augenblick erinnern kann. (Der Schwerpunkt liegt auf PB für
DOS.) Der Verfasser hat sich wirklich Mühe gegeben bei seinen Recherchen
und z. B. Josef Kirschbaum den deutschen Vertrieb von PowerBASIC am
Telefon befragt:
http://www.antonis.de/
Außerdem gibt es auf der Site Bereiche über PureBasic und "Blitz Basic",
letzteres wird afaik vor allem zur Spieleprogrammierung benutzt.
Gruss Elek Keine Ahnung wer,warum und was da in PB läuft jedenfalls hat VB eine
Funktion InputBox-Funktion die ein sehr hässliches EingabeFenster erzeugt.
also:
x = InputBox("Text im Fenster","Fenstertitel") ' diverse optionale Parameter
wie Position _
Defaultrückgabewert, zugeordnete Hilfedatei usw. gibt's auch noch.
Aber benutzen tut sowas keiner weil es fürchterlich aussieht. Irgendwie habe ich den Verdacht, daß die PowerBASIC-Entwickler die
Programmierer zu einem funktionalen Programmierstil verleiten
möchten, es gibt nämlich in den PowerBASICs für Windows kein INPUT
für Zahlen mehr.
Früher ging sowas:
INPUT "Stundenlohn: " stundenLohn
wochenLohn = stundenLohn * wochenArbeitszeit
Nun muß man sowas machen:
LINE INPUT "Stundenlohn: " t$
stundenLohn = VAL( t$ )
wochenLohn = stundenLohn * wochenArbeitszeit
Oder mit einer Funktion:
stundenLohn = xInput!( "Stundenlohn:" )
wochenLohn = stundenLohn * wochenArbeitszeit
FUNCTION xInput!( ask$ ) LOCAL PRIVATE
PRINT ask$+" ";
LINE INPUT t$
xInput! = VAL( t$ )
END FUNCTION
Komisch. Oder wollen die dadurch die Sprache kompakt halten?
Oder geht es um eine strengere Datentypentrennung; weil das alte
INPUT sowohl Zahlenvariablen als auch Textvariablen bedienen konnte?
Oder hat VB kein INPUT für die Eingabe von Zahlen via Tastatur mehr
und PowerBASIC wurde daran angepaßt?
Rätselnd Elec Hallo!
In PowerBASIC liesse sich eine Zeitmeissung, wie ich sie in
w3.programming erwähnte habe, u. U. realisieren.
Jede Funktion oder Prozedur wird so gebaut:
{FUNCTION|SUB} routinename ( parameter list ) _
[LOCAL|SHARED] _
[PRIVATE|PUBLIC] _
[AS datatype]
$if %TIMECHECK
call timechecker( referenz to this routine )
$endif
[Code der Routine selbst]
$if %TIMECHECK
call timechecker( referenz to this routine )
$endif
[letzter Befehl der Routine]
END {FUNCTION|SUB}
Dabei werden die $if-$endif-Blöcke nur kompiliert, wenn %TIMECHECK
den Wert 1 hat, $if ist eine Meta-Anweisung an den Kompiler.
Ich weiß aber bisher nicht, wie ob eine Routine in PowerBASIC
überhaupt eine Referenz auf sich selber kennt.
bye elec Hallo!
PowerBASIC-Programmierer finden hier als Binärdatei #8 eine neue
Farbdefinition für die IDE von PowerBASIC für DOS. Diese Farbdefinition habe
ich mit PB 3.2 erstellt, ich nehme aber an, daß sie ebenso für PB 3.5
verwendet werden kann. Wie diese Farbdefinition übernommen wird, kann der
Beschreibung von Binärdatei #8 entnommen werden.
Gruss Elec Hallo Chefkoch!
Normalerweise lege ich auch für jedes kleine Programmierprojekt ein
eigenes Verzeichnis an. Ich finde nur, daß die IDE von PowerBASIC
für DOS das geradezu behindert, weshalb ich es beim Einsatz von PB
manchmal lasse. Mir geht das ziemlich auf den Zeiger.
Die IDE von PowerBASIC ist meiner Erfahrung nach eine Art Variante
der IDE von Turbo-C oder Turbo-Pascal.
bye elec Hallo Elek!
Ob es nun Projekte gibt oder nicht, dem Problem, einerseits möglichst viele
Module für alle möglichen Aufgaben zur Verfügung zu haben und andererseits
immer feststellen zu können, was nun zu was gehört, bin ich so begegnet,
dass ich ein Verzeichnis "lib" habe, für jedes "Projekt" (auch ganz kleine)
ein eigenes Verzeichnis anlege und für Dateien, die von, sagen wir,
Projekt Z benötigt werden, aus dem Projekt Z - Ordner einen symbolischen
Link in das Library-Verzeichnis anlege.
DOS kennt ja keine Links, deswegen würde ich zu einem Trick greifen:
lib-Verzeichnis anlegen, die Dateien, die zum DOS-Projekt Z gehören in
dessen Verzeichnis kopieren und ein Mini-Progrämmchen schreiben, dass nach
einer Änderung der Dateien im "lib"-Verzeichnis alle Projekt-Verzeichnisse
durchgeht und nachsieht, ob dort eine Library-Datei existiert, deren Datum
älter ist als das von der Schwester im "lib"-Verzeichnis, ggf. wird die
Datei im Projekt-Verzeichnis aktualisiert.
Wichtig ist dann dabei, dass Aktualisierungen _nur_ bei den Dateien
vorgenommen werden, die im "lib"-Verzeichnis stehen und dass nach jeder
Änderung dort auch das Synchronisations-Progrämmchen aufgerufen wird. Man
könnte, falls man die eigene Selbstdisziplin als nicht allzu hoch
einschätzt, vorsichtshalber auch die Dateien aus "lib", die
in den Projektverzeichnissen liegen, auf "nur lesen" setzen. Hallo Programmierer!
Nach meiner Erfahrung mit meinem Projekt "Header-Kürzer" ist es mit
PowerBASIC für DOS schwierig, größere Programme zu erstellen.
In modernen Editoren für Web-Sites oder Javaprogrammierung kann man
meist ein Projekt anlegen, d. h. die Bedienoberfläche führt eine
Liste aller zum Projekt gehörenden Dateien, speichert den Pfad zum
Ordner, unterhalb dessen diese Dateien liegen u. dgl. m.
Die komplexen Softwareentwicklungsumgebungen von Microsoft oder
Borland bieten diese Möglichkeit ganz selbstverständlich.
Bei PowerBASIC für DOS ist das anders, es gibt keine Projekte. Und
die Bedienoberfläche legt eher nahe, keine gesonderten Ordner für
ein Projekt anzulegen.
Der Quellkode des Header-Kürzers enthält seit einiger Zeit ziemlich
viele Verweise ($include, $link) auf anderen Dateien. Meine Absicht
war, den Quellkode der inzwischen nicht mehr ganz kleinen
Hauptprogrammdatei übersichtlicher zu machen, wobei ich den
Ratschlägen von Dirk Hilger, dem Entwickler der PowerTOOLS gefolgt
bin.
Das Ergebnis finde ich inzwischen fragwürdig. Will ich die
Quelltexte auf einen anderen Computer übertragen, um das Programm
dort zu kompilieren oder zu ändern, geht die Sucherei los. Das war
ein Grund, warum ich früher den Quellkode lieber in weniger, wenn
möglich in einer Datei gehalten habe. Wer weiß denn später, wenn er
lange nicht mehr mit dem Quellkode zu einem bestimmten Programm zu
tun hatte, noch genau, welche 20 Dateien zusammen das Programm
ergeben?
Ich beschäftige mich jetzt wieder mehr mit grundlegenden Fragen wie
ein Programm entwickelt werden sollte.
Mit dem Header-Kürzer bin ich gegenwärtig unzufrieden, weil die
Entwicklungmethode meinem Gefühl nach zu unübersichtlich und nicht
flexibel genug ist. Bisher sehe ich keinen Ansatz, wie ich mit
PowerBASIC für DOS umfangreichere Programme erstellen könnte, ohne
das Gefühl zu bekommen, daß es irgendwie falsch läuft.
Also lese ich zur Zeit mal wieder in Büchern über Softwareprojekte,
in älteren und gerade neu besorgten.
Gruss Elek Hi Kronn!
> Nee, Kronn, ich hab' nur ziemlich viel mit HTML und seinem Drumherum
> zutun gehabt.
Ich habe nur gefragt, weil es mir auch schon mal im Chat passiert ist,
dass ich Umlaute z.B. als ü geschrieben habe. Außerdem habe ich
-gerade als ich meine Webseite gestaltet habe- sehr viel in diesen Stil
gedacht.
Wer lesen, lachen und löschen kann, ist klar im Vorteil...
Kronn Hi Elek!
> <raussuch>
> [...]
> </raussuch>
<frage type="text/kronn">
Benutzt du das Internet in letzter Zeit ohne Browser, der HTML in
schöne bunte Seiten übersetzt? Oder arbeitest du gerade an einem
komplizierten Webauftritt? Oder entwickelst du gerade eine XML-DTD?
</frage>
Wer lesen, lachen und löschen kann, ist klar im Vorteil...
Kronn Hallo Elek!
Diese Doubles, die in 8 Byte gespeichert werden, liegen möglicherweise im
"IEEE"-Format vor. Offenbar gibt es eine Übereinkunft über die (binäre)
Darstellung von Gleitkommazahlen hoher Genauigkeit; aus meinen Atari-Zeiten
glaube ich mich erinnern zu können, dass Doubles dort auch in 12 Byte
gespeichert werden konnten und dann eine höhere Genauigkeit aufwiesen.
Interessant ist das wohl insbesondere, um die Werte zwischen verschiedenen
Rechenoperationen herumzureichen und Fehler durch Rundungen oder
Überschreitung des Wertebereichtes möcglichst klein zu halten.
Hallo Elek!
Im Prinzip funktionierte der Umgang mit Direktzugriffsdateien schon seit
MS-Basic 1.0 in etwa so, wie von Dir beschrieben. Allerdings wich i.d.R.
die Notation davon ab, d.h. man tat nicht so, als läge eine echte Struktur
vor, sondern definierte einen Datensatz, indem man Variablen mit einer
bstimmten Zeichenzahl vorgab und dann diese Variablen mit Werten füllte. Hallo Chefkoch!
Mich hatte ursprünglich irritiert, daß jemand von komprimierter
Darstellung schrieb und dabei besonders betonte, daß die doubles in
8 Byte gespeichert sind. Außerdem erinnerte ich mich gleich an einen
Haufen in PB eingebauten Konvertierungsfunktionen, die ich bisher
noch nie benutzt habe und die irgendwelche Microsoft-Formate
zugänglich machen, die für mich bisher eher ein reizloses Rätsel
waren.
Inzwischen habe ich nachgelesen, was in den sehr ausführlichen
Handbüchern zu PowerBASIC 3.x darüber steht. Tatsächlich sind 8 Byte
zumindest in PowerBASIC ganz normal für eine doppeltgenaue
Fliesskommazahl:
Sowohl in der Online-Dokumentation für PB 3.5 (DOS) als auch denen
für die neueren PowerBASIC-Kompiler für Windows steht sinngemäß
Double-precision floating-point numbers are 64-bit (8 byte)
numbers with a range of ±4.19x10^-307 to ±1.67x10^308 and an
accuracy of 16 digits.
(Daneben hat PB allerdings auch 10-Byte-Fliesskommazahlen und die
früher hier schon mal kurz diskutierten BCD-Zahlen, das sind
"dezimal-binär-kodierte Festkommazahlen" mit 8 oder 10 Byte.)
Der IEEE-Standard für die Zahlendarstellung spielt bei PB auch eine
Rolle, ich habe darüber früher mehrmals etwas in den Handbüchern
gelesen ...
<raussuch>
"QuickBasic verwendet die Schlüsselwörter CVSMBF, CVDMBF, MKSMBF$
und MKDBMBF$, um Fliesskommazahlen nach dem alten Muster (nicht
IEEE-Standard) in Strings und zurück zu konvertieren. PowerBasic
hat äquivalente Befehle, [...]" (1)
"PowerBasic verwendet den IEEE-Standard für mathematische
Fliesskomma-Rechnungen, während das interpretierte Basic mit dem
eigenen Microsoft-Format arbeitet.
Sollten Sie mit dem interpretierendem Basic erzeugte Random-
Dateien besitzen, benötigen Sie die Microsoft/IEEE-
Übersetzungsfunktionen [...], um die einfachgenauen und
doppeltgenauen Fliesskomma-Daten in diesen Dateien lesen und
schreiben zu können." (2)
</raussuch>
Genug der Zitate. Ich werde mir gleich mal die Abschnitte
durchlesen, welche sich mit dem Problem der Dateikonvertierung
beschäftigen. Eine Frage wäre z. B.:
Wie kann ich möglichst unmittelbar oder einfach erkennen,
welches Format vorliegt?
(Natürlich könnte ich einfach zu lesen versuchen und auf eine
Fehlermeldung hoffen. Aber ob das funktioniert oder besonders
klever ist?)
bye elec Nee, Kronn, ich hab' nur ziemlich viel mit HTML und seinem Drumherum
zutun gehabt. Hallo!
<gruebel>
Kompakte Felder in Random-Files.
(double compacted to 8 bytes)
</gruebel>
Sagt das jemandem was? Ist das dieser Microsoft-Kram, für den
PowerBASIC 92,78 Umwandlungsroutinen hat?
<wuehl in der dokumentation type="neugierig">
...
bye elek Hallo BASIC-Programmierer,
Mit PowerBASIC benutzt man Random-Dateien so wie es das folgende
Beispiel zeigt. Weiß jemand, ob das unter QBasic (oder in anderen
BASIC-Dialekten) genauso geht oder welche Unterschiede es gibt?
*Erzeugen, schreiben und lesen von Random-Access-Dateien* (1)
1. Eine Datei öffnen:
OPEN filespec FOR RANDOM AS [#]filenum [LEN = recordsize]
2. Die Datensatzstruktur angeben:
TYPE StudentRecord
LastName AS STRING*20 ' 20-character string
FirstName AS STRING*15 ' 15-character string
IDnum AS LONG ' Student ID as long integer
Contact AS STRING*30 ' Contact in case of emergency
ContactPhone AS STRING*40 ' phone number
ContactRel AS STRING*8 ' Relationship to the student
AverageGrade AS SINGLE '
END TYPE
3. Eine neue Variable des Datentyps StudentRecord deklarieren:
DIM Student AS StudentRecord
4. Den Felder des anwenderdefinierten Datentyps Werte zuweisen:
Student.LastName = "Potter"
Student.FirstName = "Harry"
Student.IDnum = "999"
Student.Contact = "Joanne K. Rowling"
Student.ContactPhone = "(999) ROWLING"
Student.ContactRel = "creator"
Student.AverageGrade = "99.9"
5. Datensätze in die Datei schreiben:
PUT #fileNumber, recordNumber, Student
6. Datensätze aus einer Datei lesen:
GET #fileNumber, recordNumber, Student
7. Den Dateipuffer in die Datei schreiben und die Datei schließen:
CLOSE #fileNumber
Gruss Elec Hallo!
Unter folgendem URL finden sich ein paar kurze Quelltexte für PB/CC, die
PowerBASIC Console Compiler
http://www.mse2000.com/pc/pbcc/1.htm
Die Quelltexte sind direkt verlinkt, um sie wie gewohnt mit Zeilenumbrüchen
und Einrückungen lesen zu können, müssen sie erst als Text abgespeichert
werden.
Gruss Elek Hallo Cyrion!
elek am 10.07.02 / 20:50 (Mittwoch):
> Vielleicht schreibe ich nachher mal ein kleines Testprogramm, das
> die Geschwindigkeit beider Verfahren vergleicht.
Ich habe nun beide Lösungen bei der Suche nach einem einzelnen
Zeichen getestet.
Mit PowerBASIC für DOS (PB 3.2) ist Deine Methode erheblich, um ein
Vielfaches schneller, mit PowerBASIC für Windows (PB/CC) ist meine
ein paar mal schneller. Der Unterschied liegt daran, daß PB/CC eine
eingebaute Funktion StrReverse$() hat, wenn die nicht da ist, also
unter PB 3.2 frißt der LOOP in meiner selbstkodierten Funktion
StrReverse$() die sonstige Zeitersparnis.
Um überhaupt darstellbare Unterschiede zu bekommen, 500 x 10
Vergleiche und 833 x 6 Vergleiche durchführen lassen, also mit jeder
Methode insgesamt ca. 10.000 Vergleiche.
Für DOS-Programme werde ich mir also RInstr() nach Deinem Ansatz
bauen. :)
Gruss Elec Hallo Cyrion!
Meine RInstr-Imitation unterscheidet sich von Deinem Vorschlag auch
dadurch, daß ich nur nach einem *einzelnen* Zeichen suche, weil es
das ist, was ich bisher immer gebraucht habe.
Gruss Elek Hallo Cyrion,
Deine Methode würde auch funktionieren, ich erläutere mal knapp wie
es bei meiner geht:
Meine Funktion RInstr() benutzt zwei Elemente, die für einen BASIC-
Programmierer nicht ohne weiteres verständlich sind:
- die PowerBASIC-Funktion Tally().
- die Hilfsfunktion StrReverse$() und
Tally() zählt, wie oft ein Zeichen oder eine Zeichenkette in einer
anderen vorkommt, beispielsweise liefert *Tally( "1232242", "2" )*
die Zahl 4, weil "2" genau viermal in "1232242" vorkommt.
StrReverse$() baut aus der ihr übergebenen Zeichenkette eine zweite
Zeichenkette in der die Reihemfolge der Zeichen umgedreht ist,
beispielsweise liefert *StrReverse$( "1234" )* "4321".
Ich gehe damit so vor:
- Wenn das gesuchte Zeichen einmal oder gar nicht vorkommt,
dann ist natürlich das Ergebnis von RInstr gleich dem von Instr,
also benutze ich dann einfach Instr.
- Wenn nicht, baue ich mir hilfshalber einen umgedrehten String
und setze Instr darauf an. Anschließend errechne ich aus der
String-Länge und der Fundstelle im umgekehrten String die
Fundstelle im nicht umgedrehten String.
Ich habe Instr den Vorzug vor einer Zählschleife, die den String von
hinten nach vorne zeichenweise vergleicht, gegeben, weil ich
vermute, daß eine eingebaute Funktion wie Instr besonders schnell
ist.
Vielleicht schreibe ich nachher mal ein kleines Testprogramm, das
die Geschwindigkeit beider Verfahren vergleicht.
Gruss Elek Hi Elek
---------
Irgendwie blicke ich bei deinem rinstr Emulator nicht durch. Ich wuerde
vermutlich das erste zeichen von dem Vergleichsstring nehmen und auf
gleuchheit von hinten nach vorne mit den Zeichen des Hauptstrings vergleichen.
Ist das erste Zeichen als gleich erkannt, wird der vergleich ueber alle
nachfolgenden Zeichen Zeichen gemacht.
Tschau
<<<<<< C Y R I O N >>>>>> Hallo!
Hier im Files-Bereich liegt nun ein Text, in dem alle X-Basic-Entsprechungen
zu QuickBasic-Schlüsselwörtern aufgelistet sind.
Mir persönlich wird schon beim Lesen einiger Funktionsnamen schlecht,
ich wollte XBasic vielleicht mal ausprobieren; aber das muß ich mir
wirklich nicht antun:
XstChangeDirectory() statt ChDir
XstGetCommandLineArguments() statt Command$
XstGetEnvironVariables() statt Environ$()
XstGetFilesAndAttributes() statt FileAttr()
XstMakeDirectory() statt MkDir
XstGetTimeAndDate() statt Time$
XstStartTimer() statt Timer()
Hat der XBasic-Entwickler einen Pascal-Programmierer verschluckt? Ist er von
einem COBOL besessen? Oder ist er einfach ein Pedant, der sich von
irgendwelchen Prinzipien seiner Universitätslehrer nicht lösen kann?
Morgen sehe ich das vielleicht toleranter; aber für heute ist XBasic für mich
gestorben. XstSuelz() Pfff!
bye elec Hallo!
Hier nun ein RInstr() für PowerBASIC, ich habe das für PB 3.2
geschrieben, es funktioniert aber auch für die neueren PB-Dialekte
für Windows, allerdings muß man dann die Definition der Funktion
"StrReverse$()" weglassen, da diese Funktion zum festen Befehlsumfang
von PB/CC 2ff, PB/DLL und PowerBASIC for Windows gehört.
----- Start des PowerBASIC-Quellkodes ------------------------------
FUNCTION RINSTR( txt AS STRING, searchedSign AS STRING ) LOCAL PUBLIC AS WORD
LOCAL answer??, rPos??, reversed$
IF TALLY( txt$, searchedSign$ ) <= 1 THEN
answer?? = INSTR( txt$, searchedSign$ )
ELSE
reversed$ = StrReverse$ ( txt$ )
rPos?? = INSTR( reversed$, searchedSign$ )
answer?? = LEN( txt$ ) - rPos?? + 1
END IF
RINSTR?? = answer??
END FUNCTION 'RINSTR??()
FUNCTION StrReverse$( BYVAL txt AS STRING ) PRIVATE
'
' liefert die umgekehrte Zeichenfolge
'
LOCAL stringLen%
LOCAL i%
LOCAL invers$ : invers$ = ""
LOCAL nPos%
stringLen% = LEN(txt)
FOR i% = stringLen% TO 1 STEP -1
invers$ = invers$ + MID$(txt, i%, 1)
NEXT i%
StrReverse$ = invers$
END FUNCTION 'StrReverse$()
----- Ende des PowerBASIC-Quellkodes -------------------------------
bye elec Hallo Chefkoch!
> [Die PowerBASICer wären auch schön dumm, wenn sie Fans verbieten
> würden, mit ihrem Namen zu werben.]
Ja, das denke ich natürlich auch; aber da ich schon die
wahnsinnigsten Dinge über Urheberrechtsstreitigkeiten gelesen habe,
wollte ich auf Nummer Sicher gehen.
> Mit GFA geht das übrigens nicht, weil deren Chef den Laden [...]
> in den Konkurs geführt hat. (*)
Das es keine offizielle Bezugsquelle für GFA mehr gibt, habe ich vor
ein paar Jahren festgestellt. Damals hatte ich angeregt durch die
Diskussionen hier in der CN versucht, mir GFA für DOS zu besorgen.
Tatsächlich bekam ich dann auch ein Angebot; aber konnte damals
einfach das Geld nicht aufbringen.
bye elec Hall0
Meine wahre Gedenke vom Tage, diesem:
Ich will ein kleines PB/CC-Programm debuggen. Ja, da gibt es doch
diese zwei BASIC-Befehl, den der Atari 800XL nicht, der Commodore
jedoch kannte: TRON und TROFF. "Tron" der frühe Kultfilm vieler
Programmierer. Also setze ich ein paar Zeilennummern und schreibe
"TRON" in eine Zeile. - Merkwürdigerweise kein Syntaxhighlighting,
was mich sofort stutzig macht. Also starte ich die Online-
Dokumentation und lese, statt TRON und TROFF heiße es in PB/CC nun
"TRACE ON" und "TRACE OFF". Ja, TRACE kannte ich auch schon.
Aber mal ehrlich, was geht in den Compiler-Autoren vor? PowerBASIC
für DOS kennt TRON und TROFF, plötzlich ist das, was jeder BASIC-
Programmierer im Schlaf kennt, nicht mehr gut genug und wird durch
TRACE ON/OFF ersetzt.
I wonder why! Wer denkt sich sowas aus? PB hat Tron getötet?
Ah! Nun kommt mir ein neues Feature des Kompilers zu statt: Macros.
Jetzt geht Elek sich zwei Macros definieren:
MACRO TRON = TRACE ON
MACRO TROFF = TRACE OFF
Elek ist ein User! Tron lebt. Hallo Elek!
Ich meine, die Power-Basicer wären auch schön dumm, wenn sie einem Fanclub
verbieten würden, mit ihrem Namen zu werben ;-)
Aber im Ernst: Ja, finde ich gut. Mit GFA geht das übrigens nicht, weil
deren Chef den Laden rechtzeitig vor Erscheinen des WWW auf dem
Normaluser-Desktop in den Konkurs geführt hat. (*)
(*) Vermutlich muss ich hierzu bald eine Gegendarstellung veröffentlichen. Hallo BASIC-Programmierer!
Der Quelltext enthält an mehreren Stellen Formulierungen, die fast
altbekannt wirken, an denen Standardfunktionen von BASIC aber etwas
anders benutzt werden als man es von älteren BASIC-Dialekten gewohnt
ist.
-------------------------------------------------------------------
CHR$()
--------
Liefert bekanntlich das Zeichen zu einem ASCII-Wert,
beispielsweise ist "CHR$( 65 )" das große "A".
PowerBASIC erlaubt außerdem eine Aufzählung von ASCII-Werten, um
einen String zu konstruieren, beispielsweise "Chr$( 13, 10 )"
oder "Chr$( 132, 148, 129, 225 )" für "äöüß".
Neu in PB/CC 3 und PB/Win 7 ist nun die folgende Möglichkeit:
> t$ = CHR$( 0 TO 255 ) 'ein String aus allen 256 ASCII-Zeichen
> 'Die Kleinbuchstaben in eben erzeugten String t$ werden
> 'durch Grossbuchstaben ersetzt:
> REPLACE CHR$( 97 TO 122 ) WITH CHR$( 65 TO 90 ) IN t$
-------------------------------------------------------------------
MCASE$()
----------
Es gibt nun neben den Funktionen UCase$() (upper case) und
LCase$() (lower case) eine Funktion MCase$(), die "mixed-case
text" erzeugt.
t$ = UCase$( "mit der U-Bahn")
' ergibt "MIT DER U-BAHN"
t$ = LCase$( "mit der U-Bahn")
' ergibt "mit der u-bahn"
t$ = MCase$( "mit der U-Bahn")
' ergibt "Mit Der U-Bahn"
-------------------------------------------------------------------
OPTIMIERTE SELECT-STRUKTUR
----------------------------
> SELECT CASE AS CONST$ inptFileType$
>
> CASE "xpf"
> .
> .
> .
> CASE "def"
> .
> .
> .
> CASE ELSE
> .
> .
> .
> END SELECT
Mit den optionalen Zusätzen "AS CONST$", "AS CONST" oder "AS LONG"
erzeugen "PB/CC 3" und "PB/Win 7" auf schnellen Ablauf optimierte
Select-Strukturen für spezielle Vergleichsarten.
Gruss Elec Hallo!
Ich habe einen Text über PowerBASIC 3.2 (für DOS) hier im Files-Bereich
abgelegt; er hat den Titel "100 ways PowerBASIC 3.2 beats QuickBasic"
und stellt einen offensiven Vergleich zwischen QuickBasic und PB 3.2 an.
bye elec Hi
---
Alles zum thema GFA Basic ab jetzt bitte in die Rubrik ST, aufrufbar mit
atari, st, w3.st, w3.ata, w3.gfa und gfa
Tschau
<<<<<< C Y R I O N >>>>>> Hallo!
Quellkode für die Windows-Kompiler von PowerBASIC unterscheidet sich
in einigen Punkten von dem für PowerBASIC für DOS. Ich beschreibe
hier vier einfache Unterschiede, es gibt aber noch mehr.
BENANNTE STRING-KONSTANTEN
Im Beispielcode vereinbart die Zeile
$ProgName = "Filterdateikonverter cnf2Unix 2.1"
eine String-Konstante. PowerBASIC für DOS kannte nur benannte
Integer-Konstanten etwa "%MAXPERSONEN".
"$ProgName" wurde im Beispielprogramm als Platzhalter für den
Text "Filterdateikonverter cnf2Unic 2.1" vereinbart. Der Inhalt,
auf den dieser Platzhalter verweist, wird während des Compilierens
festgelegt und kann zur Programmlaufzeit nicht geändert werden.
VERÄNDERTE METAKOMMANDOS FÜR DEN COMPILER
Da benannte String-Konstante durch ein Dollarzeichen "$"
eingeleitet werden, sollen Metakommandos an den Compiler
durch ein Gitterzeichen "#" eingeleitet werden. Wenn es also
früher hieß
$COMPILE EXE "programmname.exe"
schreibt man für die Windows-Kompiler von PowerBASIC
#COMPILE EXE "programmname.exe"
DIE HAUPTFUNKTION
Wie ein C-Programm muß jedes Programm für PB/CC oder "PowerBASIC
for Windows" eine Hauptfunktion haben. Im Beispiel:
FUNCTION PBMAIN() AS LONG
.
.
.
END FUNCTION 'PbMain&()
Jedes Programm für PB/CC, einen "PowerBASIC Console Compiler"
muß entweder eine Funktion PBMAIN oder eine Funktion WINMAIN
enthalten. DLL-Code für "PowerBASIC for Windows" muß entsprechend
eine Einsprungfunktion enthalten, die DLLMAIN, LIBMAIN oder
PBLIBMAIN heißt.
ANDERE SCHLÜSSELWORTE FÜR DIE REICHWEITE VON VARIABLEN
Während PowerBASIC für DOS allen Routinen zugängliche Variablen
mit dem Schlüsselwort "SHARED" deklarierte, benutzen die
PowerBASIC-Dialekte für Windows dafür "GLOBAL".
bye elek Hallo Chefkoch, hallo Besucher der BASIC-Rubrik!
Ich wollte die META-Keywords und die META-Description der Rubrik
BASIC so ergaenzen, dass Leute, die sich fuer PowerBASIC
interessieren, vielleicht eher hierher finden. Deshalb und um
rechtlichen Streitigkeiten vorzubeugen, hatte ich an PowerBASIC Inc.
geschrieben:
| Do you allow me to include your name and the name of
| your products in the meta description, the meta
| keywords or every other part of this www site?
Tom Hanlin, ein Mitarbeiter der Firma hat daraufhin um den URL
gebeten. Und ich habe ihm mit dem direkten Link zur BASIC-Rubrik und
dem zur Homepage der "Chat Noir" geantwortet.
Eine freundliche Antwort ist soeben bei mir eingetroffen.
Tom Hanlin am 02.07.02 an elek@jpberlin.de:
> Looks good! Please feel free to borrow our descriptions and
> use our product names in your meta sections. You may also
> use any of the product graphics and PowerBASIC logos from
> our web site, if they would be helpful to you.
Der C.-koch kann sich auch ein bisschen freuen, dass die Site
gefaellt, denke ich.
bye elec Hallo BASIC-Programmierer,
das Folgende ist ein vereinfachter Ausschnitt aus einer meiner
Programme. Ich habe einige Dinge gelöscht oder simplifiziert, damit
das Beispiel übersichtlicher ist und die interessanteren Code-
Abschnitte in den Vordergrund geraten. Ich möchte Euch damit ein
einfaches Beispiel für die Möglichkeiten von PowerBASIC im
allgemeinen und "PB/CC 3.0" im speziellen geben.
In einer Folgenachricht werde ich das Beispiel erläutern.
bye elec
----- start of PB/CC 3.0 code ---------------------------------
'COMPILERBEFEHLE:
#COMPILE CON "cnf2Unix.exe"
#DIM NONE
#OPTION VERSION4
#DEBUG ERROR OFF
'GENERELLE DATENTYP-DEFAULTS:
DEFSTR c,s
DEFLNG i,j,n,m
'STRING-KONSTANTEN:
$ProgName = "Filterdateikonverter cnf2Unix 2.1"
$STAB = $SPC + $TAB
'ROUTINEN AM ENDE DER DATEI:
DECLARE FUNCTION getCollateString$ ()
FUNCTION PBMAIN() AS LONG
'VARIABLEN DEKLARIEREN:
DIM replaceCounter AS GLOBAL LONG
DIM fileLine AS GLOBAL STRING
'DATEINAMEN:
DIM inptFile AS GLOBAL STRING : inptFile = "input.txt"
DIM outpFile AS GLOBAL STRING : outpFile = "output.txt"
'PARAMETER DES AUSGABEFENSTERS:
CONSOLE NAME $ProgName
CURSOR OFF
COLOR 7
CONSOLE SCREEN 25, 80 'Consolen-Fenster-Groesse n x m Zeichen
'ACTIONS: ===========================================================
CLS
?
PRINT UCASE$($ProgName)
IF LEN(DIR$(inptFile)) = 0 THEN
COLOR 8 'gray
PRINT "Die Eingabedatei " + $DQ + inptFile + $DQ + " liegt nicht ";
PRINT "im aktuellen Verzeichnis."
PRINT "Das Programm wird daher ohne weitere Aktionen beendet."
GOTO stopnow
END IF
OPEN inptFile FOR INPUT AS #1
OPEN outpFile FOR BINARY ACCESS WRITE LOCK WRITE AS #2
inptFileType$ = RTRIM$( REMAIN$( inptFile, "." ) )
COLOR 8
IF inptFileType$ <> "def" THEN PRINT "Die Datei wird ueberarbeitet: ";
SELECT CASE AS CONST$ inptFileType$
CASE "xpf"
[...]
CASE "def"
FILESCAN #1, RECORDS TO count&
DIM defLine( 0 TO count&-1 ) AS STRING
LINE INPUT #1, defLine() TO i&
amountOfDefLines& = i& - 1
cu$ = getCollateString$()
ARRAY SORT defLine$(), COLLATE cu$
DO
defLine$ = TRIM$( defLine$(0) )
IF defLine$ = "" THEN
ARRAY DELETE defLine$(0)
ELSE
EXIT LOOP
END IF
LOOP
FOR n=0 TO amountOfDefLines&
defLine$ = TRIM$( defLine(n) )
IF ( LEFT$( defLine$, 1 ) = "#" ) THEN
ITERATE
ELSEIF ( defLine$ <> "" ) THEN
PUT$ #2, MCASE$( defLine$ ) + $LF
INCR replaceCounter
ELSE
EXIT FOR
END IF
NEXT n
CASE ELSE
[...]
END SELECT
endOfFileActions:
CLOSE
backFile$ = EXTRACT$( inptFile, ".") + ".las"
IF LEN( DIR$( backFile$, 6 ) ) > 0 THEN
KILL backFile$
END IF
NAME inptFile AS backFile$
NAME outpFile AS inptFile
?
COLOR 8 'gray
PRINT "Anzahl ersetzter Zeilenenden =" + STR$( replaceCounter )
stopnow:
COLOR 7 'white
SLEEP 1000
END FUNCTION 'PbMain&()
FUNCTION getCollateString$() PRIVATE
LOCAL answer$, t$, match$
t$ = CHR$( 0 TO 255 )
REPLACE CHR$( 97 TO 122 ) WITH CHR$( 65 TO 90 ) IN t$
match$ = CHR$( 131 TO 134, 142, 143, 160, 181 TO 183, 198 )
REPLACE ANY match$ _
WITH REPEAT$( LEN( match$ ), "A" ) _
IN t$
match$ = CHR$( 130, 136 TO 138, 144, 210 TO 212)
REPLACE ANY match$ _
WITH REPEAT$( LEN( match$ ), "E" ) _
IN t$
match$ = CHR$( 139 TO 141, 161, 214 TO 216, 222)
REPLACE ANY match$ _
WITH REPEAT$( LEN( match$ ), "I" ) _
IN t$
match$ = CHR$( 147 TO 149, 153, 155, 162, 224, 226 TO 229)
REPLACE ANY match$ _
WITH REPEAT$( LEN( match$ ), "O" ) _
IN t$
match$ = CHR$( 129, 150, 151, 154, 163, 233 TO 235)
REPLACE ANY match$ _
WITH REPEAT$( LEN( match$ ), "U" ) _
IN t$
REPLACE ANY CHR$( 128, 135 ) _
WITH "CC" _
IN t$
answer$ = t$
getCollateString$ = answer$
END FUNCTION 'getCollateString$()
----- end of PB/CC 3.0 code ----------------------------------- Hallo Sebastian, hallo BASIC-Interessenten!
Sebastian, welche Möglichkeiten PowerBASIC im Umgang mit COM-
Objekten bietet, kannst Du wahrscheinlich auch indirekt dem
Befehlumfang von PowerBASIC entnehmen.
PB/CC 3.0 bietet genau folgende Funktionen um COM-clients zu
erzeugen bzw. mit ihnen umzugehen:
ACODE$
Übesetzt eine Unicode-Zeichenkette in eine ANSI-Zeichenkette.
CLSID$
Liefert eine 16 Byte (128 Bit) lange GUID-Zeichenkette,
welche eine CLSID enthält.
GUID$
Liefert einen 16 Byte (128 Bit) langen "Global Unique
Identifier" GUID/UUID.
GUIDTXT$
Liefert eine 38 Byte lange für menschliche Leser gedachte
GUID/UUID-Zeichenkette.
INTERFACE/END INTERFACE
Deklariert ein "dispatch interface", dessen Methoden und
Eigenschaften.
ISNOTHING
Bestimmt den gegenwärtigen Zustand einer gegebenen
Objektvariablen.
ISOBJECT
Bestimmt den gegenwärtigen Zustand einer gegebenen
Objektvariablen.
LET
Weist einer Variablen allgemein oder speziell einer Variant-
Variablen einen Wert zu.
OBJACTIVE
Liefert TRUE/FALSE für den Ausführungszustand eines COM-EXE-
Objekts (the running state of a COM EXE object).
OBJECT
Kommuniziert mit einem COM-Objekt über das Dispatch-Interface.
OBJPTR
Liefert den Objekt-Pointer auf eine angegebene Objekt-Variable.
OBJRESULT
Liefert das Ausführungsergebnis des zuletzt gegebenen
OBJECT-Befehls.
PROGID$
Liefert die alphanumerische PROGID-Zeichenkette (als Text)
einer gegebenen CLSID.
RESET
Löscht eine Variant-Variable und setzt sie auf %VT_EMPTY.
SET
Weist einer Objekt-Variablen die Referenz auf ein Dispatch-
Interface zu.
UCODE$
Übersetzt eine ANSI-Zeichenkette in eine Unicode-Zeichenkette.
VARIANT#
Liefert den numerischen Wert, den eine Variant-Variable
enthält.
VARIANT$
Liefert den Wert der dynamischen Zeichenkette, die in einer
Variant-Variablen enthalten ist.
VARIANTVT
Bestimmt den internen Datentyp der Daten, welche in einer
Variant-Variablen gespeichert sind.
bye elec Danke für den Beispiel-Code, Sebastian!
Sebastian Lange am 01.07.02 / 02:59 (Montag):
> Das war jetzt [...] ein ActiveX-Beispiel. [...]
> Kann PowerBasic da nun was in der Richtung?
Ich habe mich bisher kaum mit ActiveX beschäftigt, deshalb würde ich
das nur erkennen, wenn PowerBASIC Inc. es ausdrücklich so benennt.
Die einzigen Quellen, die mir im Augenblick über die neuen
PowerBASIC-Compiler zur Verfügung stehen, erwähnen ActiveX genau
zweimal. Die weitestgehende Erwähnung von beiden ist wirklich das,
was ich für w3.dos eingedeutscht hatte:
| PowerBASIC Inc. schreibt der Begriff ActiveX werde meistens
| benutzt, um einen spezifischen COM-Implementierungstyp zu
| beschreiben. Das COM-Konzept habe sich lebhaft entwickelt,
| herkommend von OLE über VBX und OCX bis hin zu den jüngeren
| COM-Definitionen und ActiveX.
Oder im Original aus dem Text "A COM Primer":
| As far as the history goes, COM itself has had an colorful
| evolution as it has grown from OLE (Object Linking and Embedding),
| through VBX and OCX, to the more recent definitions of COM and
| ActiveX as the design concepts have evolved. For the most part,
| the term ActiveX is used to describe a specific type of COM
| implementation, [...].
Sebastian Lange am 01.07.02 / 00:31 (Montag)
in der Gruppe w3.dos:
> [...] es sei noch gesagt das Microsoft in seinem Visual Basic COM
> primär nur über ActiveX unterstützt. Wäre zu prüfen wie PowerBasic
> das macht. Ich lese da nur Client COM/Automation Support.
In einer sehr viel ausführlicheren Produktbeschreibung steht
"PowerBASIC now supports the creation of COM client
and controller applications."
bye elec VB
Hier mal eben ganz minimalistisch ein Document mit Word drucken.
Es muss msword9.olb als verweis eingebunden werden :-)
Kann aber auch eine frühere Version sein wenns ein früheres Word tun soll.
Dim word_app As Word.Application 'Unser WordApplicationObjekt
'aus der msword9.olb
Set word_app = CreateObject("Word.Application.8")
'Hier nun der eigentliche ActiveX Aufruf. Nun ist
' es ein echtes WordObjekt. Wir übergeben die
'entsprechene ProgId. Was ProgID's sind wird
' später(anderes Posting) noch erklärt
word_app.Application.Visible = True
'Wir wollen ja was als Beweis
' sehen deswegen stellen wir Word auf sichtbar. Machen wir das
' nicht sieht der User garnichts vom Spass
word_app.Application.Activate
'Nun aktivieren wir Sie - Tada ! Word ist auf dem Bildschirm
word_app.Documents.Open FileName:="C:\Hallo.doc"
'Wir laden ein Dokument
word_app.ActiveDocument.PrintOut
'Und drucken das akive Dokument also unser eben geladenes
word_app.Quit
'So nun könnenwir die Word Instanz auch mal
'wieder zu machen - Verschwunden ist es :-)
Set word_app = Nothing
' Jetzt geben wir noch unsere Wordvariable frei und das wars
' auch schon
Also erschreckend einfach die ganze Sache. Bleibt anzumerken das alles aber
auch wirklich alles in Office entsprechend fernsteuerbar ist. Dokumentation
gibts für lau bei Microsoft.
Über Netzwerke werden gerade aus SAP Datenbank-Systemen oftmals solche
Print-Server realisiert. Tabellen werden auf diese Weise in Excel angelegt und
entsprechend verarbeitet und und ...
Das war jetzt kein direktes COM sondern ein ActiveX-Beispiel.
Irgendwie hab ich nun vergessen zu klären wie ActiveX nun in VB genau läuft,
aber kommt noch. Kann PowerBasic da nun was in der Richtung? Hallo!
Hinweis für PowerBASIC-Interessenten: In der neuesten Version meines
Header-Kürzers für ZConnect-Nachrichten setze ich die PowerTOOLS I und II ein,
das sind zwei kommerziell vertriebene Software-Bibliotheken für PowerBASIC 2.1
oder 3.2.
Bemerkenswert ist, daß alle Funktionen die damit bereitgestellt werden, vom
Autor der Bibliotheken Dirk Hilger in Assembler kodiert wurden. Mit diesem
PowerTOOLS verfügt man über einige schnelle Alternativen zu Standardbefehlen
von PB/DOS und über Erweiterungen, mit denen sich z. B. SAA-konforme
Bedienoberflächen erstellen lassen.
Gruss Elek Hallo!
In der Ausgabe für Mai/Juni der Programmierzeitschrift Toolbox hat
Hildegart Hausmann über die Stärken von PB/DLL 6.0 berichtet, dessen
Nachfolger "PowerBASIC for Windows 7.0" kürzlich auf den Markt
gekommen ist.
Frau Hausmann hat ein paar kleine Tests gemacht. PowerBASIC bestacht
dabei, was auch meinen Erfahrungen entspricht durch sehr kleine
Dateien, so kompilierte das kleinste mit PowerBASIC denkbare
Programm - das allerdings nichts tut - zu ca. 5 KByte.
Naheliegenderweise erzeugt PowerBASIC u. a. dadurch kleine Dateien,
dass die Windows-API, also "win32api.inc" genutzt wird.
Als Geschwindigkeitstest führte Frau Hausmann folgendes Programm
aus:
-------- start code ---------------------------
#COMPILE EXE
FUNCTION PBMAIN() AS LONG
LOCAL x##, y##, t!, i&
x##=1 : y##=1.000001
t!=TIMER
FOR i&=1 TO 100000000
x##=x##+y##
NEXT
t!=TIMER-t!
MSGBOX "100 Mill. Rechenfunktionen in " _
& Chr$(13) & FORMAT$( t! ) & "Sekunden"
END FUNCTION
-------- end code -----------------------------
Dieses Progrämmchen brauchte laut Frau Hausmann unter Windows 98SE:
1,60 Sekunden unter einem AT-Pentium mit 200 MHz
0,44 Sekunden unter einem Pentium 4 mit 1,6 GHz
Für die Ausführungsgeschwindigkeit ist es entscheidend, daß die
Programme unter einem ecten 32-Bit-System laufen, einige Versuche
von mir auf einem System mit Windows 95 unter einer 486er-CPU
ergeben einen dramatischen Geschwindigkeitsverlust. (Es gab
allerdings auch eine ältere PB/DLL-Version für 16-Bit-Windows.)
Ich empfehle, *unter 16-Bit-Windows* PB 3.5 zu verwenden, obwohl das
Testprogramm - mit PB/DLL 6.0 kompiliert - immer noch deutlich
schneller war als die PB 3.5 Version, scheint mir das für komplexere
Programme teilweise umgekehrt zu sein.
Dabei ist die EXE, wie mein Versuch ergab, gerade mal 8.704 Byte
groß, der DOS-Compiler PB 3.5 erzeugt für das gleiche Programm
übrigens eine EXE, die ca 23.000 Byte groß ist. Der Code sähe für
PowerBASIC für DOS kaum anders nämlich so aus:
-------- start code ---------------------------
$OPTIMIZE SPEED
x##=1 : y##=1.000001
t!=TIMER
FOR i&=1 TO 100000000
x##=x##+y##
NEXT
t!=TIMER-t!
CLS
STDOUT "100 Mill. Rechenfunktionen in" & Str$( t! ) & " Sekunden"
END
-------- end code -----------------------------
Die oben verwendeten Variablen x## und y## gehören übrigens zu
PowerBASICs Datentyp "Extended-precision floating point", 10 Byte
großen Fliesskommazahlenrepräsentationen. Schon PowerBASIC für DOS
unterscheidet sich von älteren BASIC-Dialekten wie QuickBASIC durch
leistungsfähige neue Datentypen. Bot z. B. QuickBASIC zwei
Stringtypen und vier numerische, so stehen in PowerBASIC drei
Stringtypen und *elf* numerische Datentypen zur Verfügung.
Das Fazit von Hildegart Hausmann: Mit PowerBASIC für Windows könne
man schnell schnelle kleine Programme erstellen.
Gruss Elek Hallo Cyrion!
Ich hatte sogar mal vor, mir GFA und alle Handbücher dazu von
exklusiver Stelle zu kaufen, aber das ist damals an einem gewissen
Geldmangel gescheitert.
PowerBASIC ist übrigens auch schon länger am Ball, denn PowerBASIC
2.0 erschien 1990 - für DOS natürlich - und war schon die
Weiterentwicklung von Borlands Turbo BASIC 1.0/1.1.
bye elek Hi
---
Das Zitat galt allerdings schon seit 15 Jahren, wo GFA Basic rauskam
Tschau
<<<<<< C Y R I O N >>>>>> >Wer mir nun immer noch nicht glaubt, daß BASIC lebt und alte
>BASIC-Programme mit Zeilennummern und Spagetticode mit >modernem Basic so viel
zutun
haben, wie ein Fahrrad mit einem >Motorboot, der möge von mir aus weiter schlafe
n.
BASIC RULEZ :-) Hallo!
ganz wie ich annahm, war die kürzlich hier erwähnte Bereitstellung
kostenloser Updates der Kompiler PB/CC und PB/DLL durch PowerBASIC
Inc. eine Aktion, mit welcher die Aufmerksamkeit der Lizenznehmer
geweckt werden sollte, damit eine kurz darauf auf den Markt geworfene
ganz neue Kompiler-Generation besser aufgenommen wird.
PowerBASIC Inc. bietet nun drei neue Produkte an:
- PowerBASIC Console Compiler ver 3.0, (kurz: PB/CC 3.0)
- PowerBASIC Compiler for Windows ver 7.0 (kurz: PB/Win 7.0)
- PowerBASIC Forms ver 1.0,
Der "PowerBASIC Compiler für Windows" ist der Nachfolger von "PB/DLL",
das Produkt wurde offiziell umbenannt. "PowerBASIC Forms" ist ein
völlig neues Produkt zum Erstellen von GUIs für PB/Win-Programme.
Für jeden der beide Kompiler PB/CC 3.0 und PB/Win 7.0 kann man auf
Wunsch zusätzlich ein gedrucktes Handbuch erwerben. Auf die in einem
PowerBASIC-Forum gestellte Frage, ob das wirklich neue Handbücher
seien, antwortete ein Firmenvertreter "new versions, new manuals".
Die Produktbeschreibung von PB/CC 3.0 (1) listet knapp 100 (in Worten:
hundert!) neue Eigenschaften der Sprache auf, u. a. wurden eine
Vielzahl von Befehlen erweitert und einige Funktionen wie iif()
eingeführt, das zwar nicht unbedingt nötig ist, aber in anderen
Programmiersprachen gebräuchlich und gelegentlich sehr praktisch. Die
Zahl der nützlichen Neuerungen übertrifft meine Erwartungen deutlich.
Unter diesen knapp 100 neuen Eigenschaften von PB/CC 3.0 sind
beispielsweise die folgenden:
- ACODE$() translates unicode strings to ansi equivalent
- CHOOSE(index&, choice1, choice2...) returns one of
several numeric values, based upon the value of an index
- CSET$() returns a centered string with optional padding
character
- FILESCAN rapidly scans a sequential or binary file to
obtain the number of text strings or packed strings it
contains and the length of the longest string
- IIF(expr, truepart, falsepart) returns one of two numeric
values, based upon a true/false condition
- JOIN$() converts an entire string array to a single
dynamic string using specified codes as delimiters for
each element
- UCODE$() translates ansi strings to the unicode equivalent
Wer mir nun immer noch nicht glaubt, daß BASIC lebt und alte BASIC-
Programme mit Zeilennummern und Spagetticode mit modernem Basic so
viel zutun haben, wie ein Fahrrad mit einem Motorboot, der möge von
mir aus weiter schlafen.
Gruß Elek Hallo!
Da ich gerade ein Programm von PB/CC 2.11 in PB 3.5 portiert habe,
mache ich dazu hier ein paar Anmerkungen für alle PowerBASIC-
Interessenten.
PB 3.5 ist der aktuellste DOS-BASIC-Compiler der Firma PowerBASIC
Inc.; PB/CC ist der "PowerBASIC Console Compiler", erzeugt 32-Bit-
Native-Code für Windows 95, 98, Windows NT 3 oder 4.
Der Hersteller wirbt seit jeher damit, daß ein Umstieg von
PowerBASIC für DOS, also von PB 2.1, 3.2 oder 3.5, auf PB/CC oder
PB/DLL sehr leicht sei. Das stimmt schon, aber ich warne trotzdem
davor, sich diesen Umstieg bzw. die Portierung von Kode vom DOS-
Kompiler zu einem der PowerBASICs für Windows zu leicht
vorzustellen. Es sind allerhand kleine Änderungen vorzunehmen, für
die es meines Wissens kein Konverterprogramm gibt, also ist alles
händisch zu erledigen. Wenn man dies das erste Mal macht und unter
Zeitdruck steht, kann diese Kodeanpassung die Geduld erheblich
strapazieren. Es ist also großzügig Zeit einzuplanen. Kennt man
PB/CC schon eine Weile, dann sind diese Kodeanpassungen unter
günstigen Umständen recht zügig zu bewältigen.
Ganz anders sieht es aus, wenn man PB/CC-Kode abwärts in PB3.5-Kode
umsetzen möchte, und zwar deshalb, weil PB/CC einen größeren
Befehlsumfang hat als PowerBASIC für DOS. PB/CC beherrscht z. B.
einige sehr nützliche String-Manipulationen, die man in PB 3.5 erst
selber implementieren muß: PARSE$, REMAIN$, REGEXPR und REGREPL.
Gerade die beiden zuletzt genannten, die Reguläre Ausdrücke (regular
expressions) in PowerBASIC implementieren, kann man IMO nur mit
erheblichem Aufwand in PowerBASIC für DOS implementieren.
Für BASIC-Programmierer, die vor allem für Windows 9.x oder Windows
NT programmieren, lohnen sich PB/CC oder PB/DLL also nicht nur, weil
damit für 32-Bit-Windows-Systeme schnellere und kleinere Programme
erzeugt werden als mit PB 3.5, sondern weil einige sehr
leistungsfähige Befehle Leistungen ermöglichen, die sonst vielleicht
nicht in vertretbarer Zeit umzusetzen sind.
Da ich sowohl PB 3.5 also auch PB/CC nun schon eine Weile benutze,
ist die Abwärts-Portierung für mich allmählich einfacher geworden,
weil ich inzwischen ein paar Bibliotheks-Dateien in PB3.5-Kode
geschrieben habe, welche Funktionen von PB/CC implementieren.
Mein aus Erfahrung gesättigter Rat ist, den Aufwand für keine Kode-
Portierung zu unterschätzen!
bye elec Hallo GFA-Leute
Unser Betrieb hat sich vor 10 Jahr für GFA-Basic (16-Bit Version)
entschieden als Programmplatform. Alles ganz und gut bis es Windows XP
gab.
Jetzt aber drehen unsere Producte nicht mehr. Etwas geht schief im
GFARUN10.DLL. Wisst Ihr vielleicht eine Lösung (entweder Patch oder
neue
DLL)?
Herzlichen Dank im Voraus
Marco Bleekrode
Kubus Informatiesystemen
Geldropseweg 47
5611 SC Eindhoven
Niederlände
T: +31 40 213 1950
F: +31 40 213 8560 Hallo Sebastian;
ich mache mal ein paar Anmerkungen, einen Code-Schnipsel von mir
suche ich auch raus und schicke ihn in die CN oder an Dich per Emil.
WIESO ÜBERHAUPT POWERBASIC?
PowerBASIC für DOS war früher IMO deswegen erste Wahl, weil PB noch
weiterentwickelt wurde, als Microsoft sich schon entschlossen hatte,
den BASIC-Compiler für DOS nicht mehr zu ändern oder zu supporten.
PowerBASIC Inc. hingegen erklärt noch heute, daß es noch mindestens
eine neue Version von PowerBASIC für DOS geben werde. IMO ist
PowerBASIC für DOS das einzige nennenswerte *lebende* DOS-BASIC.
Für Leute, die früher vor allem mit PowerBASIC für DOS programmiert
haben, liegt es dann erst einmal nahe, unter Windows PB/CC oder
PB/DLL zu benutzen; die Syntax ist recht ähnlich und man ist mit den
Produkten von PowerBASIC Inc. bisher zufrieden.
PB/CC
ist ein sogenannter "Consolen Compiler", der 32-Bit-native-code
erzeugt. Keine Ahnung, ob der Begriff "Consolen Compiler" überhaupt
anderswo benutzt wird. Jedenfalls war es der erste Schritt von
PowerBASIC in die Windows-Welt und es handelt sich um einen Compiler,
der keine graphischen Sachen unterstützt, die Programme laufen quasi
in einer Art DOS-Fenster. Damit lassen sich z. B. auch CGI-Programme
schreiben, praktisch alles, was im Batch-Betrieb läuft, ohne daß
irgendwer mit der Maus rumklicken soll.
PB/DLL
dient zum programmieren von Windows-DLLs oder allein lauffähigen
Programmen (EXE). Ich habe das mal benutzt, um eine DLL zu für ein
Toolbook-Projekt zu programmieren (gehörte zu meiner Multimedia-
Ausbildung bei SNI). Es ging um Fehlertoleranz bei den Antworten
eines Lernquiz, also etwa, wenn ein Kind statt Jerusalem Jerusalen
oder Geruhsalem eingibt. Die Routine errechnete eine Zahl zwischen 0
und 1, die den Grad der Übereinstimmung ausdrückte. Toolbook, ein
Multimedia-Autorensystem, vor allem für Lernprogs, kann DLLs
benutzen, das ließe sich auch innerhalb von Toolbook mit der
Scriptsprache programmieren, aber eine PowerBASIC-DLL ist ganz sicher
um einiges schneller.
PowerBASIC Inc.
bietet also vor allem diese drei Compiler an:
- PB 35, den aktuellen DOS-Compiler;
- PB/CC 2.11, den Consolen Compiler;
- PB/DLL 6.11, im Prinzip ihr Spitzenprodukt.
vor geraumer Zeit teilte die Firma außerdem mit, sie arbeite an einem
PowerBASIC für Linux, PowerBASIC Inc. ist aber mit Informationen zu
kommenden Programmen extrem restriktiv, d. h. sie IMO PowerBASIC für
Linux genau erst dann wieder erwähnen, wenn es ausgetestet und zum
Verkauf fertig ist. Es gibt nur eine einzige offizielle
Stellungnahme, die ich kenne, laut der die Arbeit an diesem Linux-
BASIC laufe und zu Hoffnung Anlaß gebe.
Die Produktinfo von PowerBASIC Inc. findest Du unter
http://www.powerbasic.com/products/
DIE OFFIZIELLE WERBUNG
PowerBASIC Inc. wirbt für PB/DLL seit Jahren mit dem Argument der
Geschwindigkeit. Früher erzeugte Visual BASIC AFAIK keinen native
Code. Im Handbuch zu "PB/DLL 6" steht einleitend u. a.:
PB/DLL is a compiler that allows BASIC programmers to write
industry-standard DLLs ans EXEs in a familiar language. DLLs
created with PB/DLL can be used by programs written in any other
language that supports 32-bit Windwos DLLs, such as C++, Delphi,
PowerBuilder, Visual Basic and Visual Basic for Applications
(VBA).
PB/DLL ist the perfect solution for those BASIC programmers who
have been looking for a way to optimize the time-critical
section of their programs, but had neither time nor the
inclination to learn a whole new language. PB/DLL is the same
familiar BASIC language with two inportant differences: compiled
PB/DLL code typically has 3 to 23 times the performance of
compiled VB 5 code, and EXEcutables generated by PB/DLL are
typically 4 to 40 times smaller! Thjis means you get native
machine code, which lets your programs run as fast as they
possibly can, and small DLLs that do nnot require any additional
external or runtime modules.
[...]
While PB/DLL can readily access all functions of the windows
32-bit API, it was designed as an add-on to visual design tools
rather than as an replacement. In this regard PB/DLL is the
perfect complement to Visual Basic. Use Visual Basic for what it
does best -- userinterface and forms design. Use PB/DLL for what
ist does best -- size, speed, number cruncing, calculations,
threads, all of your mission-critical code.
Ich habe keine Super-Anwendungen in PB/CC geschrieben, aber ich werde
mal gucken, ob ich Dir was schicken kann, das ich in PB/CC-Code
programmiert habe.
Gruss Elek Nun mach doch mal einer genauer Werbung für dieses PowerBasic.
Was kann es ?
Oder was macht es anders als die derzeit führende Programmiersprache Visual
Basic ?
Ich bin sehr interessiert und würde mich sogar auf ein wenig Syntax freuen
:-)
Als Dankeschön würde ich dann immer posten wie VB an die Sache rangeht und
wir könnten objektiv vergleichen. Hallo!
Das Update von PB/CC 2.0 auf die Version 2.11 braucht anders als ich hier erst
geschrieben hatte nur einen und nicht zwei Downloads.
Die Version 2.11 behebt vor allem einige Dinge, die PBCC-User schon lange
gestört haben werden, und schafft neue Möglichkeiten, die sich zweifellos
viele PBCC-Programmierer schon lange gewünscht haben:
- Die Online-Hilfe, die bekanntlich ihre Macken hatte,
wurde überarbeitet und ist nun so gut, wie man es
erwartet.
- Die Absonderlichkeit, daß der Kompiler nur EXE-Files
nach der Regel "8.3" erzeugte, wurde beseitigt, PB/CC
akzeptiert nun für alle Files lange Dateinamen.
- Endlich können den Stringkonstanten auch mit der
Funktion CHR$() definiert werden. Der Kompiler
erzeugt außerdem automatisch und stillschweigend
12 String-Konstanten, beispielsweise $DQ für
ASCII 34 (DQ von Double-Quote).
Diese Aufzählung der neuen Eigenschaften von PB/CC 2.11 ist nicht vollständig,
aber es sind diejenigen, die IMO am augenfälligsten sind und von den meisten
PBCC-Programmierern vermißt worden sind.
bye elek Hallo!
PowerBASIC Inc. hat neue Versionen von PB/CC und PB/DLL
bereitgestellt. Lizenznehmer von PB/CC 2.0 oder PB/DLL 6.0 können
kostenlos auf die Versionen 2.1 bzw. 6.1 updaten. Hat man eine
dieser neuen Versionen installiert, kann man noch ein aktuelles
Service-Pack installieren und hat damit schließlich PB/CC 2.11 bzw.
PB/DLL 6.11. Weitere Informationen findet Ihr auf der Web-Site
"http://www.powerbasic.com/".
bye elek Ich werde ihn eiskalt töten..... oder es geht so ab, wie bei jenem Film mit Bette Middler, in welchem
die Entführer fast soweit getrieben werden, Geld dafür zu zahlen,
daß die Geisel wieder verschwindet. Dieser Steve Ballmer scheint
ja ein recht agiler, nerviger Propagangist zu sein.
---- Hallo Lad-Sebastian!
So, Du nimmst Ballmer als Geisel? Da hoffe ich mal sehr, dass auf Deine
Forderungen nicht eingegangen wird ;-) Lad-Sebastian am 28.07.01 / 12:03 (Samstag)
in der Rubrik /w3.basic:
> Ich hoffe ihr seid nun alle glücklich!!!
Wenn Du jetzt noch geschrieben hättest, PowerBASIC würde durch die
amerikanische Regierung verboten, dann würde ich noch Allen
kitnappen und zum Alex mitbringen. ;)
____________
regards elec Ich hoffe ihr seid nun alle glücklich!!! BASIC wird es von Microsoft also in
der Form nicht mehr geben. VB stirbt und niemand unternimmt etwas. Ich werde
wohl eine Protestaktion auf dem Alex veranstalten-danach Steve Ballmer als
Geisel nehmen und erst wieder frei lassen wenn wieder tragbare zustände
herrschen..Schnüff! $DIM ALL
DECLARE FUNCTION createYear% (INTEGER)
DIM n AS INTEGER : n = 0
DIM i AS INTEGER : i = 0
DIM year AS INTEGER : year = 0
MAIN:
CLS
WHILE 1
?
INPUT "Jahreszahl eingeben: ", n
IF n=9999 THEN EXIT LOOP
year = createYear%(n)
? "year = " + STR$(year)
WEND
? : ? "Programm terminiert."
END
FUNCTION createYear%(y AS INTEGER)
DIM answer AS LOCAL INTEGER
DIM javaSystemsYear AS LOCAL INTEGER
DIM systemsYear AS LOCAL STRING
systemsYear$ = RIGHT$( DATE$, 4 )
? "systemsYear$ = " + systemsYear$
javaSystemsYear% = VAL(systemsYear$) - 1900
? "javaSystemsYear% = " + STR$(javaSystemsYear%)
IF y < 100 THEN
IF ( y > javaSystemsYear% - 100 ) THEN
answer% = y + 1900
ELSE
answer% = y + 2000
END IF
ELSE
END IF
createYear% = answer%
END FUNCTION 'createYear() Hallo Frank!
Frank am 01.04.01 / 04:13 (Sonntag)
in der Rubrik /w3.basic:
Elek>> Ich habe eine FUNCTION "getLenContent%()",
Elek>> die so aussieht:
Frank> Danke, diese Kritiken sind wirklich sehr hilfreich,
Frank> um die die Auswertung der Headerzeilen möglichst
Frank> gut nachvollziehbar und damit sicher zu programmieren
Frank> und um mögliche Fehlerquellen rechtzeitig zu erkennen.
Wenn es um ev. Fehler geht, müßten meine Funktionen ev. anders
aussehen; ich weiß nicht, wie sicher es ist, daß die Header/
Puffer die richtige Form haben.
Sicherer wäre dann vielleicht folgendes:
============================================================
'--- LEN: ---
FUNCTION getLenContent%(header$)
DIM sContent AS LOCAL STRING
DIM nContent AS LOCAL INTEGER
sContent = LTrim$( LTrim$(header$, "LEN:") )
sContent = rtrim2$(sContent) 'wird eigentl. nur gebraucht,
'wenn die Funktion einen String
'und keine Ganze Zahl zurück-
'geben soll. getLenContent$()
nContent = VAL(sContent)
FUNCTION = nContent
END FUNCTION 'getLenContent%()
FUNCTION rtrim2$(s AS STRING)
IF LEN(s) > 1 THEN
FUNCTION = RTrim$(s, Right$(s,2))
ELSE
FUNCTION = s
END IF
END FUNCTION 'rtrim2()
============================================================
Weitere Antworten von mir stehen dann erstmal nur in der Rubrik
KomAgent
Gruss Elec
----------
----
"Anstreichen heißt nicht malen."
Leonardo Da Vinci ________
Hye ELEK,
> Ich habe die Prozedur LENauswertung() durch eine FUNCTION
> "getLenContent%()" ersetzt, die so aussieht:
[...]
Danke, diese Kritiken sind wirklich sehr hilfreich,
um die die Auswertung der Headerzeilen möglichst
gut nachvollziehbar und damit sicher zu programmieren
und um mögliche Fehlerquellen rechtzeitig zu erkennen.
\bye
Frank Hallo BASIC-Freunde und XP-Nutzer!
Frank am 31.03.01 / 18:46 (Samstag)
in der Rubrik /KOMAGENT:
> ___________________
> Hye Elek und Points,
>
> als kleines PB-Projekt bastele ich ja an einem
> Ausgangsfilter zu CrossPoint, um das KOM-Format zu
> unterstützen. Die ersten Routinen sind fertig.
> Außerdem sende ich mal eine Todo-Liste.
>
> (Alle Interessenten, die direkten Zugang zur CN haben,
> können sich als Mitglied in die interne Rubrik KomAgent
> eintragen lassen.)
>
> Das kleine Programm hier liest den ersten Header aus und
> zeigt bestimmte Headereinträge an.
> [...]
Ich habe die Prozedur LENauswertung() durch eine FUNCTION
"getLenContent%()" ersetzt, die so aussieht:
============================================================
'--- LEN: ---
FUNCTION getLenContent%(header$)
DIM sContent AS LOCAL STRING
DIM nContent AS LOCAL INTEGER
sContent = LTrim$(header$, "LEN:")
sContent = rtrim2$(sContent)
nContent = VAL(sContent)
FUNCTION = nContent
END FUNCTION 'getLenContent%()
FUNCTION rtrim2$(s AS STRING)
FUNCTION = RTrim$(s, Right$(s,2))
END FUNCTION 'rtrim2()
============================================================
Der komplette Code kann in der Rubrik KomAgent nachgelesen
werden, in die jeder auf Wunsch als Leser eingetragen werden
kann, der dies hier deutlich lesbar kundtut.
Gruss Elec
---------- Hallo Frank,
ich habe den Code gerade in die Entwicklungsumgebung von PB 3.5
geladen, um ihn nachzuvollziehen und dazu etwas hilfreiches
bemerken zu können.
bye elec
-------- ___________________
Hye Elek und Points,
als kleines PB-Projekt bastele ich ja an einem Ausgangsfilter
zu CrossPoint, um das KOM-Format zu unterstützen.
Die ersten Routinen sind fertig.
Außerdem sende ich mal eine Todo-Liste.
(Alle Interessenten, die direkten Zugang zur CN haben,
können sich als Mitglied in die interne Rubrik KomAgent
eintragen lassen.)
Das kleine Programm hier liest den ersten Header aus und
zeigt bestimmte Headereinträge an.
Für LEN: wird schon ein Unterprogramm aufgerufen,
daß die Länge separiert.
Damit kann das Programm rekursiv aufgerufen, den
nächsten Header finden.
Ziel ist es als Ausgangsfilter bestimmte Aktionen
an den zum Versand bereitgestellten Puffern zu generieren.
Die Parameter werden über das Feld Stichworte
angegeben und sind zunächst nur /b und /t und ein
Filename.
Wenn der Headereintrag Stichwort: diese enthält, wird
die Empfängerrubrik auf /BIN oder /TXT gesetzt, damit
die Nachricht in den Binär- oder den Files-Bereich einer
Rubrik gesandt wird.
Wenn die beiden Zeilen:
CALL AllAuswertg(header$,allhead$) '| deaktivieren +
'? header$ '| aktivieren zum TEST
so geändert werden, daß CALL auskommentiert wird
und der Print-Befehl durch Entfernen des Hochkommas
aktiviert wird, wird der gesamte Header des ersten
Eintrags angezeigt.
Nach der ZConnect-Beschreibung folgt dem Header immer eine
Leerzeile, was sich das Programm zunutze macht, daß
ein Puffer-File immer im Binärmodus öffnet.
--------------------------------zip-----------------------------------
filename$ = "f:\x" '| hier den Namen eines
'| ZConnect-Puffers angeben
DEFINT A-Z
ON ERROR GOTO fehler
GOSUB fehler1
header$ = ""
allhead$ = ""
infile$ = ""
zeilen$ = ""
sTab$ = Chr$(9)
leer$ = Chr$(32)
ptr% = 0
ptr1% = 0
i = 0
k = 0
CLS
OPEN filename$ FOR BINARY AS 1
WHILE NOT EOF(1)
GET$ #1,1,A$
header$ = header$ + A$
IF A$ = CHR$(13) AND i = 1 THEN
EXIT LOOP
ELSE
i = 0
END IF
IF A$ = CHR$(10) THEN
' k = k + 1 '| Counter2
WHILE (TALLY(header$,sTab$) > 0)
REPLACE sTab$ WITH leer$ IN header$
WEND
CALL AllAuswertg(header$,allhead$) '| deaktivieren +
'? header$ '| aktivieren zum TEST
header$ = ""
i = i + 1 '| Counter1
END IF
WEND
CLOSE
'? "Headerzeile:" k '| zeigt Anzahl der Header an s. Counter2
END '| ** reguläres Programmende **
'--- ALLHEAD ---
SUB ALLAuswertg(header$, allhead$)
LOCAL tmp%
tmp% = 1
ptr% = INSTR(tmp%,header$,":")
allhead$ = LEFT$(header$,ptr%)
SELECT CASE allhead$
CASE "EMP:" '| Brett(er) oder UserInnen?
? allhead$ '| CrossPostings/Binär-Mehrfachversand ?
CASE "KOM:"
? allhead$
CASE "Stichwort:" '| enhält Parameter und Dateinamen bei UserInnen
? allhead$ '| für Bretter existiert noch Zusammenfassung:
CASE "TYP:" '| falls vorhanden immer BIN
? allhead$
CASE "FILE:" '| falls vorhanden immer TYP: BIN
? allhead$
CASE "MAILER:"
? allhead$
CASE "X-XP-ARC:" '| dürfte eigentlich nicht vorkommen
? allhead$
CASE "LEN:"
CALL LENAuswertg(header$,LENgth&)
? allhead$
? LENgth&
END SELECT
END SUB
'--- LEN: ---
SUB LENAuswertg(header$,LENgth&)
LOCAL tmp%, LENgth$
tmp% = 0
zeilen$ = "LEN:"
tmp% = INSTR(1,header$,zeilen$)
IF tmp% <> 0 THEN
tmp% = 1
zeilen$ = "LEN:"
ptr% = INSTR(tmp%,header$," ") + 1
ptr1% = LEN(header$) - 1
tmp% = ptr1% - ptr%
LENgth$ = MID$(header$,ptr%,tmp%)
header$ = ""
LENgth& = VAL(LENgth$)
ELSE
LENgth& = 0
END IF
END SUB
fehler:
IF ERR = 68 THEN
PRINT "Das Device nicht gefunden"
ELSE
PRINT "Fehler: ";ERR;" unbekannt"
END IF
PRINT "Programmabbruch"
CLOSE
END '| und Schluß
fehler1:
filename$ = UCASE$(filename$)
W$ = RTRIM$ (filename$) '| entfernt anhaengende LZ aus der Eingabe
X$ = DIR$ (W$) '| holt die erste Datei mit dem Muster
IF X$ = "" THEN '| nicht existierende Files werden sonst mit
? "Die Datei ";filename$;" existiert nicht"
? "Programmabbruch" '| 0 byte Länge angelegt
END '| und Schluß
END IF
RETURN
--------------------------------zap-----------------------------------
Die Todo-Liste sieht so aus:
Beschreibung der Abhängigkeitsbeziehungen der Headereinträge
SEEK also den Dateizeiger setzen, bei rekursivem Aufruf
Parameterauswertung Stichwort
--------
Auswertung der Abhängigkeitsbeziehungen und
-Generierung neuer Headereinträge wie LEN, FILE, DDA
-Anhängen von Dateien
-Löschen von Headereinträgen wie Stichwort, X-XP-ARC
-Konvertierung der Headereinträge wie LEN zu KOM o. MAILER ändern
\bye
Frank Chefkoch am 05.03.01 / 01:41 (Montag)
in der Rubrik /w3.basic:
> Auf dem Atari hatte ich eine Masse kleiner Utilities für
> dies und das geschrieben. Seit Linux-Zeiten bin ich aber
> dazu übergegangen, die schier unüberblickbare Masse von
> Standard-Utilities zu benutzen [...]
Hi Brutus, Leute!
Heute wurde mir Linux 7.1 geliefert, allerdings habe ich es noch
nicht installiert.
( Perle, ich wollte einfach die schlauen Handbücher allzeit
griffbereit haben. )
bye elec
-------- Hi Brutus,
witzig fand ich selber an dem Code-Zitat mit etwas zeitlichem Abstand,
daß dort "$DIM NONE" steht und trotzdem so gut wie alle Variablen
ausdrücklich deklariert sind; aber genau das unterscheidet vielleicht
einen PowerBASIC-Freak von einem rechtgläubigen Pascal-Programmierer:
Ich bin aus eigenem Interesse, nämlich um selber den Überblick zu
wahren sehr gründlich, aber ich mache es nicht zum Kult.
Für die Nicht-Programmierer: "$DIM NONE" ist die ausdrückliche
Anweisung an den PowerBASIC-Compiler, daß keine Variable vor Gebrauch
mit DIM angemeldet werden muß, d. h. der Compiler moniert das Fehlen
einer solchen Anmeldung, fachsprachlich Deklaration genannt, nicht.
Gleichzeitig wimmelt der Code des Straßennamensgenerators - das ist
der Witz - vor DIMs.
Noch einmal für Nicht-Programmierer: Deklaration nennt man die
ausdrückliche Mitteilung an den Compiler oder Interpreter, also an das
Programm welches den vom Programmierer geschriebenen Programmtext,
sprich Code verarbeitet, daß man innerhalb eines Programmes einen
bestimmten Namen (=Bezeichner) für eine bestimmte Art von Speicher
(=Variable bzw. Datentyp) benutzen möchte.
Wenn ich nicht gerade zwei Glas guten Rotwein getrunken hätte, würde
ich das garnicht erklären, es liest ja doch kein Nicht-Programmierer.
Übrigens habe ich einige Leute kennengelernt, die
Programmierunterricht hatten oder sogar gaben, die nicht sauber
zwischen Deklaration, Initialisierung in Definition einer Variablen
unterscheinden können; ob man das als guter Programmierer wissen muß,
ist eine andere Frage. Ich weiß gern gut bescheid.
bye elec
----
"Anstreichen heißt nicht malen."
Leonardo Da Vinci Hi Brutus,
zuviel der Ehre, ich bin einigermaßen erfahren in PowerBASIC, solange
es nicht um Inline-Assembler oder Grafikprogrammierung geht und habe
mir durch ne Menge Lesen, Turbo-Pascal, Modula 2, Nikolaus Wirth und
Ratlosigkeit über eigenen lange nicht mehr eingesehenen Code einen
einigermaßen sauberen Code-Stil angeeignet. Es gibt haufenweise
raffiniertere und umfassender befähigte PowerBASIC-Programmierer; was
ich mache, mache ich aber - wenn auch nicht rasend schnell - recht
ordentlich.
bye elec
-------- Hallo Elek!
Ich war schnon immer überzeugt davon, dass Du ein ganz hervorragender
PB-Programmierer bist, und jetzt erst recht ;-)
Auf dem Atari hatte ich eine Masse kleiner Utilities für dies und das
geschrieben. Seit Linux-Zeiten bin ich aber dazu übergegangen, die schier
unüberblickbare Masse von Standard-Utilities zu benutzen, wo ich allerdings
immer erst fleißig lesen muß, bis es dann wirklich losgeht. Vorteil ist
aber, dass ich beim nächsten Mal, wenn wieder ein ähnliches Problem ansteht,
deutlich weniger lesen muß, um zu einee Lösung zu gelangen. Hallo Brutus,
vielleicht hast Du recht, was mein Progrämmchen betrifft, habe ich
inzwischen beim wiederholten Lesen des Codes eingesehen, daß nur ein
irrelevater Fehler drin steckte, eher ein Formfehler, die sauberste
Lösung ist bisher wohl die Version für PowerBASIC für DOS.
Allerdings ist es nur eher banales Programm, bloß wirst Du solche
Programme zur schnellen Selbsthilfe auch schon oft geschrieben haben,
ich hatte gerade kein Programm in Reichweite, mit dme ich das sonst
hätte ausfiltern können und, weil das Problem so überschaubar und
banal ist, bot sich ein eigenes Progrämmchen auch vom Aufwand her an.
Im Vergleich zu meinem Straßennamensgenerator oder Anima ist es
natürlich ein winziges Code-Cookie. Habe heutemal kurz in den Code
des Straßennamensgenerators reingeguckt. (Tatsächlich habe ich am
Wochenende einen Anruf aufgezeichnet gefunden, in dem jemand aus dem
Rathaus nach der EXE fragt. Wenn ich jetzt nur wüßte, wo die letzte
Version liegt. Können diese Schluffis nicht besser auf die von mir
seinerzeit übergebene EXE aufpassen?)
Eine Fassung von MkList32.bas, die hier rumliegt, fängt jedenfalls
dann schon so schlicht an:
#IF 0
------------------------------------------------------------------------------
Programm ........ MkList32.BAS
Funktion ......... Das Programm liest eine ASCII-Datei, IN der je Zeile
ein Strassenname steht und generiert daraus
mehrere HTML-Dateien.
Ausserdem erzeugt das Programm eine ASCII-Datei,
die alle Strassennamen auflistet, und zwar je Zeile
einen Strassennamen. Dieser OUTPUT dient wiederum
als INPUT fuer weitere Serviceprogramme.
Dies ist ein proprietaeres Programm, das vorerst nur
fuer die Erstellung des Neukoellner Strassennamens-
verzeichnisses programmiert wird.
Ableitung ........ MKLIST3.BAS vom Mi, 21.06.2000, 13:33 Uhr
Stand ........... So, 01.07.2000, 00:40 Uhr
Bemerkung ........ alle FUNCTIONS/SUB-Routinen sind IN routines.sub
kodiert und werden vom Compiler eingebunden
06.06.2000: Unterverzeichnisse werden selbst erzeugt
24.06.2000: PB/DOS-Version IN ein PBCC-Programm.
Compiler/Sprache .. PBCC 2.0
Zielsystem ....... PC unter Win32
Betriebsystem ... Windows 95, Windows 98 oder Windows NT 4
Programmautor ... Bernd STORCK
[...]
<BerndStorck@BigFoot.de>
Copyright: Bernd Storck, Berlin, 1999/2000
-----------------------------------------------------------------------------
#ENDIF
' COMPILERBEFEHLE:
$COMPILE EXE "mklist32.exe"
$DIM NONE
$OPTION VERSION4
''UNITS DEKLARIEREN:
'FUNKTIONEN DEKLARIEREN:
DECLARE SUB addPErrorText(STRING)
'DECLARE FUNCTION CreateFilename$( Filename AS STRING, EndNumber AS DWORD )
DECLARE FUNCTION CreateLinkfileName$(STRING)
DECLARE FUNCTION CutExtension$(STRING)
DECLARE FUNCTION ExistsDir%(STRING)
DECLARE FUNCTION GetInputLine(INTEGER) AS STRING
DECLARE FUNCTION IsNoDubble() AS INTEGER
DECLARE FUNCTION kINPUT$(STRING)
DECLARE FUNCTION keyINPUTjn$(STRING)
DECLARE FUNCTION CreateFilename$(STRING, DWORD)
DECLARE FUNCTION CreateInptName$(STRING)
DECLARE SUB ParaErrorScreen(STRING, STRING, STRING, STRING)
DECLARE SUB Print4Screen (STRING)
DECLARE SUB PrintConstLen(STRING, INTEGER)
DECLARE FUNCTION ReplaceSign$(STRING)
DEFINT i
GLOBAL allNamesFileNum%
TYPE HtmlCode
Sign AS STRING*1
Html AS STRING*6
END TYPE
FUNCTION PBMAIN() AS LONG
'KONSTANTE DEFINIEREN:
%StrAnzahl = 800 'bestimmt die Groesse des Arrays zur Speicherung
'der vergebenen Dateinamen
DIM ProgName AS GLOBAL STRING : ProgName = "Make Verzeichnis 2.0"
DIM ExeName AS GLOBAL STRING : ExeName = "MKLIST32.EXE"
DIM ConsoleName AS GLOBAL STRING : ConsoleName = "HTML-Verzeichnis-Genera
tor"
DIM allowedModes AS STRING 'erlaubte Namen fuer den OutputModus
allowedModes = "index,list,liste,listen,abc,menue,name,namen,names,all,alle
,alles"
DIM sAnfuehr AS GLOBAL STRING : sAnfuehr = CHR$(34)
DIM sBindestrich AS GLOBAL STRING : sBindestrich = "-"
DIM sCR AS GLOBAL STRING : sCR = CHR$(13)
DIM sLeer AS GLOBAL STRING : sLeer = " "
DIM sLF AS GLOBAL STRING : sLF = CHR$(10)
DIM sTab AS GLOBAL STRING : sTab = CHR$(9)
DIM nTabSize AS GLOBAL BYTE : nTabSize = 4
DIM sUnterstrich AS GLOBAL STRING : sUnterstrich = "_"
'VARIABLEN DEKLARIEREN:
DIM allNamesFile AS GLOBAL STRING 'protokolliert alle Str.-namen
'in einem ASCII-File
LET allNamesFile = "allnames.txt"
DIM BgColor(1 TO 2) AS GLOBAL STRING
DIM BorderColor(1 TO 2) AS GLOBAL STRING
DIM cLine AS GLOBAL STRING
DIM DOCTYPE AS GLOBAL STRING
DIM DTD AS STRING : DTD$ = "3.2"
DIM FileCounter AS GLOBAL WORD : FileCounter?? = 0
' WORD = 0 bis 65.535
DIM FileName(1 TO %StrAnzahl) AS GLOBAL STRING ' speichert alle schon
' vergebenen Dateinamen
DIM FirstSign AS GLOBAL STRING 'Erster Buchstabe des Str.-Namens
DIM FrameNr AS GLOBAL STRING
DIM HideDubbles AS GLOBAL STRING
DIM inptFile AS GLOBAL STRING : inptFile = "powerb.txt"
DIM LinkfileName AS STRING
DIM memoFile AS GLOBAL STRING 'im Str.-namensverz. HTML fuer herkunft.h
tm
DIM nameFile AS GLOBAL STRING 'im Str.-namensverz. HTML fuer strname.ht
m
DIM namelistFile AS GLOBAL STRING 'im Str.-namensverz. HTML fuer menue.htm
DIM nFile AS GLOBAL INTEGER 'Index fuer das Dateinamens-Array
DIM outpFile AS GLOBAL STRING :outpFile = "register.htm"
DIM OutputModus AS GLOBAL STRING 'bestimmt welche Dateien erzeugt werden
' Vorgesehene Werte fuer OutputModus:
'
' - "abc" ......... Frame zur Anwahl der Anfangsbuchstaben
' - "all .......... alles
' - "allmenues" ... alle Auswahl-Frames
' - "content" ..... nur die eigentlichen Datensatzinhalte
' - "index" ....... nur einen Auswahl-Frame je Anfangsbuchstaben
' - "register" ... nur das Gesamtregister
' - "reg_idx" ..... Das Gesamtregister und je Anfangsbuchstaben einen Auswa
hl-Frame
'
DIM RowFlag AS GLOBAL BYTE 'zaehlt die aktuelle Tabellenreihe
'HOEHE UND BREITE DES BILDSCHIRMFENSTERS:
DIM ScreenWidth AS GLOBAL INTEGER : ScreenWidth% = 80
DIM ScreenHeight AS GLOBAL INTEGER : ScreenHeight% = 26
DIM simpledataFile AS GLOBAL STRING 'im Str.-namensverz. HTML fuer wappen.htm
DIM TargetFileType AS STRING
DIM tempFile AS STRING 'ein Puffer fuer die Ausgabedatei
DIM tempName AS GLOBAL STRING
DIM Ansi2Ascii$( 129 TO 255 )
DIM ReplaceField( 1 TO 20 ) AS GLOBAL HtmlCode
'AUSGABE-PARAMETER:
DIM fs_name AS GLOBAL STRING 'Font-Size fuer den Namen
DIM fs_memo AS GLOBAL STRING 'Font-Size fuer den Memo-Text
DIM fs_simpledata AS GLOBAL STRING 'Font-Size fuer die Einzeldaten
'VARIABLEN FUER DIE FEHLERMELDUNGSROUTINEN:
DIM Fehlermeldung AS GLOBAL STRING '
DIM ErrorTitle AS GLOBAL STRING '
DIM Parametername AS GLOBAL STRING '
DIM FalscheAngabe AS GLOBAL STRING '
'Erlaeuternde Zeilen zu einer Fehlermeldung:
DIM ParaErrorText( 1 TO (ScreenHeight% -12) ) AS GLOBAL STRING
'INITIALISIEREN DER VARIABLEN:
'DEFAULTWERTE fuer die AUSGABE-PARAMETER:
fs_name = "4" 'frueher "5" (STRASSENNAME)
fs_memo = "3" 'frueher "+1" (NAMENSERKLAERUNG)
fs_simpledata = "3" 'frueher "+1" (DATUM DER BENENNUNG)
OutputModus$ = "content"
'OutputModus$ = "index" 'generiert alle HTML-Dateien fuer den Menue-Frame
'und das Gesamtregister
#IF 0
'doctype-definition:
SELECT CASE DTD$
CASE "2_0"
DTD_2_0 = "HTML 2.0"
CASE "3_2"
DTD_3_2 = "HTML 3.2"
CASE "4_0"
DTD_4_0 = "HTML 4.0"
CASE "4_0_trans"
DTD_4_0_trans = "HTML 4.0 Transitional"
CASE "4_0_frame"
DTD_4_0_frame = "HTML 4.0 Frameset"
'CASE "4_0_strict"
' DTD_4_0_strict = "HTML 4.0"
END SELECT 'DTD$
#ENDIF
DOCTYPE$ = "<!DOCTYPE HTML PUBLIC "+sAnfuehr+"-//W3C//DTD HTML"+DTD$+"//EN"+sAn
fuehr+">"
#IF 0
'DEFAULT-FARBWERTE
' fuer die Tabellen
'auessere Tabelle:
BgColor$(1) = "#FFFFCC"
BorderColor$(1) = "#FFFFCC"
'innere Tabelle:
BgColor$(2) = "#FFFFFF" 'weiss
BorderColor$(2) = "#FFFFFF" 'weiss
#ENDIF
'UMWANDLUNGS-TABELLE:
'RESTORE ReplaceFieldData:
FOR i=1 TO 7
ReplaceField(i).Sign = READ$(i)
ReplaceField(i).Html = READ$(i+1)
NEXT i
ReplaceFieldData:
DATA ü, uuml 'ue = ASCII 129
DATA ä, auml 'ae = ASCII 132
DATA Ä, Auml 'AE = ASCII 142
DATA ö, ouml 'oe = ASCII 148
DATA Ö, Ouml 'OE = ASCII 153
DATA Ü, Uuml 'UE = ASCII 154
DATA ß, szlig 'ss = ASCII 225
'MAIN PROGRAM:
CONSOLE NAME "HTML-Verzeichnis-Generator"
CONSOLE SCREEN ScreenHeight%, ScreenWidth% 'Consolen-Fenster-Groesse auf n * m
Zeichen gesetzt.
CURSOR OFF
------------
Gruss Elec
----
"Anstreichen heißt nicht malen."
Leonardo Da Vinci Und das wäre das kleine Prögrämmchen in PowerBASIC für DOS (PB 3.5):
-------------------------------------------------------------------
DEFINT i
DIM inptfile AS STRING
DIM outpfile AS STRING
DIM theSign AS STRING
FUNCTION isText%(t AS STRING)
LOCAL eofSign% : eofSign% = 26
LOCAL answer%
IF t <> "" THEN
IF ASC(t) <> eofSign% THEN
answer% = 1
ELSE
answer% = 0
END IF
ELSE
answer% = 1
END IF
FUNCTION = answer%
END FUNCTION
COLOR 14, 1 'gelb auf blau
CLS 'Fenster bekommt die definierte Hintergrundfarbe
PRINT "COPYTEXT: Filtert Zeichen aus einer Textdatei" : ?
LINE INPUT "Wie heisst die Eingabedatei? " inptfile
PRINT "Die Datei wird jetzt verarbeitet."
outpfile = "copytext.txt"
OPEN inptfile FOR BINARY AS #1
OPEN outpfile FOR OUTPUT AS #2
WHILE NOT EOF(1)
GET$ #1, 1, theSign
IF isText%( theSign ) THEN PRINT #2, theSign;
WEND
CLOSE
PRINT "Alle Dateien wurden geschlossen."
PRINT "Arbeitsergebnis ist die Datei " + CHR$(34) +_
outpfile + CHR$(34) + "."
DELAY 5
END
------------------------------------------------------------------- Hallo Elek!
Ich bin der Ansicht, dass es wohl viele Programme gibt, die eher zufällig
das Richtige tun. Das kann mitunter etwas vollkommen anderes als das sein,
was der Programmautor einmal vorhatte :-) Hallo alle,
sehe gerade, daß der Code auch noch falsch war, aber trotzdem
funktioniert hat; das kann nur bedeuten, daß ich ein Naturtalent bin.
---- Hallo Frank, hallo Leute!
Ich habe angefangen, die Kurzbiographie über Knud Hamsun
abzuschreiben, danz benutze ich Crosspoint. Nachdem ich den noch nicht
vollständigen Text geparkt hatte, waren plötzlich merkwürdige Nicht-
Textzeichen im Text: Ein paar ersetzte ich per Hand allerdings fühjrte
mein Verushc die Nachricht erneut zu verschicken, also in das
eigentlich Ausgangsbrett zu kopieren dazu, daß die Nachricht
abgeschnitten wurde, allem Anschein nach war ein Endezeichen in dem
Text.
Trotzdem ließ sich der komplette Text aus XP exportieren und mit
folgendem kleinen PowerBASIC-Programm (PBCC 2.0) konnte ich ihn
schließlich retten und in XP reimportieren:
DEFINT i,j
FUNCTION isText%(t AS STRING)
LOCAL eofSign% : eofSign = 26
LOCAL answer%
IF ASC(t) <> eofSign THEN
answer% = 1
ELSE
answer% = 0
END IF
FUNCTION = answer%
END FUNCTION
FUNCTION PBMAIN() AS LONG
CONSOLE NAME "COPYTEXT: Filtert EOF-Zeichen aus einer Text-Datei"
CURSOR OFF
DIM fileline AS LOCAL STRING
DIM inptfile AS LOCAL STRING
DIM outpfile AS LOCAL STRING
DIM theSign AS LOCAL STRING
LINE INPUT "Wie heisst die Eingabedatei? " inptfile
outpfile = "copytext.txt"
OPEN inptfile FOR BINARY AS #1
OPEN outpfile FOR OUTPUT AS #2
WHILE NOT EOF(1)
GET$ #1, 1, theSign
IF isText%( theSign ) THEN
PRINT #2, theSign;
END IF
WEND
CLOSE
END FUNCTION
In solchen blöden Sitautionen bin ich immer wieder froh, daß
PowerBASIC griffbereit ist.
Gruss Elec
---------- Da in der Überschrift stand dass sich noch keine VB-Programmierer hergetraut
haben möchte ich wenigstens offiziell anmelden (als VB-Prog.). Wenn ihr also
in Zukunft auf VB rumhacken wollt (wegen zu langsam und so) habt ihr jetzt
eine Person die man quasi direkt anschreien kann. Mal gucken was kommt... |