Engine Room - V1N3 (German)



Major Weenie tendiert dazu, ein wenig m&uuml;rbe zu werden, nachdem er die halbe Nacht auf war, um mit Mr. Worf die verschiedensten klingonischen Delikatessen, wie gakh zu probieren. Es ist dabei nicht einmal die Tatsache, da&szlig; das Essen versucht vom Teller zu kriechen, w&auml;hrend man versucht, es zu essen - es ist der Pflaumensaft, mit dem man es runtersp&uuml;lt, der mich fertigmacht. Im Hinblick auf den heutigen geschw&auml;chten Zustand des Majors werden wir uns daher auf eine kurze, einfache Lektion beschr&auml;nken.

Ich glaube, das letzte mal verlie&szlig;en wir unsere Diskussion &uuml;ber REXX mit ein paar sehr einfachen Beispielen. Nun la&szlig;t uns mal die Empf&auml;nger etwas empfindlicher einstellen und das Dateihandling untersuchen.

Nun, die meisten Dateien, die sie mit REXX ver&auml;ndern werden, werden keine Bin&auml;rdateien sein - sie k&ouml;nnten zwar eine Datenbank Applikation in REXX schreiben, aber sie sollten es nicht. Sie erinnern sich, soweit es den Major betrifft, ist REXX am besten geeignet f&uuml;r relativ einfache Aufgaben, wie Systemverwaltung. Wenn sie eine Datenbank m&ouml;chten, empfiehlt der Major DB2/2 von IBM, Approach von Lotus Development oder nehmen sie sich einen Indelible Blue Katalog und schauen sie sich andere M&ouml;glichkeiten an.

Also, welche Dateitypen werden sie h&ouml;chstwahrscheinlich mit REXX bearbeiten? Kommen sie, h&ouml;ren sie auf, mit dem Replikator zu spielen und denken sie mal nach. Richtig, Textdateien. Was ist die eine Textdatei, die man auf jedem Warp System findet, selbst, wenn es der Major installiert hat ? Richtig, README. Nun, eine Eigenschaft die README mit fast jeder anderen einfachen Textdatei gemeinsam hat, die aus einer beliebigen Ecke des Quadranten eingeflogen kommt, ist die, da&szlig; sie nicht in einzelne Seiten unterteilt ist. Und wenn wir von einer Seitenunterteilung reden, dann reden wir &uuml;blicherweise &uuml;ber das Vorhandensein des ASCII Zeichens mit der Nummer 12, das nichts anderes als ein Seitenvorschub ist. W&auml;re es nicht sch&ouml;n, wenn man vorher w&uuml;&szlig;te, wieviele Seiten ein Ausdruck von README oder einer anderen einfachen Textdatei ben&ouml;tigen wird ? B&auml;ume wachsen nunmal nicht auf B&auml;umen, wie sie wissen.

Hier ist eine M&ouml;glichkeit, das mit einer einfachen REXX Datei herauszufinden. Vergessen sie nicht, da&szlig; jede REXX Datei mit einem Kommentar beginnen mu&szlig; (und der Kommentar ist alles, was zwischen den Zeichen /* und */ zu finden ist).

Nachdem wir nun den Kommentar aus dem Weg ger&auml;umt haben, wie bekommen wir unser Programm dazu, tats&auml;chlich README oder eine andere Datei zu &ouml;ffnen und zu manipulieren. Ein einfacher Weg ist, den Dateinamen sofort beim Aufruf des Programms zu erfassen. Das passiert mit dem ARG Befehl.

Leute, so f&uuml;hlt sich mein Magen an nach all dem gakh... Tats&auml;chlich ist ARG der Befehl, mit dem sie in ihrem Programm all das erfassen k&ouml;nnen, was der Anwender in der Kommadozeile eingetippt hat. Wenn ihr Programm "countwords.cmd" hei&szlig;t dann sieht die Zeile, mit der sie in countwords die Datei erhalten k&ouml;nnen, mit der gearbeitet werden soll, so aus: ARG filename

"filename" wird, im Rahmen des Programms, die Datei, mit der sie arbeiten, sprich, ARG erfasst, was sie auf der Kommandozeile eingegeben haben und speichert es in dem Variablennamen, den sie hinter ARG angegeben haben. Wenn sie in diesem Beispiel "countwords readme" auf der Kommandozeile eingeben, wird "readme" der variable "filename" zugewiesen.

So, jetzt haben sie den Dateinamen, und was jetzt ? OK, zuerst lege ich mal diesen Disruptor weg oder lasse ihn sicher nicht so auf meinen Kopf zeigen... Egal, was ist das Schlaueste, was man zu diesem Zeitpunkt machen kann ?

Richtig, sagen sie dem Anwender, da&szlig; er es verbockt hat, wenn er &uuml;berhaupt nichts eingegeben hat. Sie k&ouml;nnen das so machen:

''' If filename = "" then Do	Say 'Sie m&uuml;ssen einen Dateinamen angeben, wenn sie COUNTWORDS aufrufen.' Say 'Bitte versuchen sie es nochmal. . .'       Exit End /* do */'''

Ok, halten wir mal kurz hier an. Zwei Probleme, die au&szlig;erhalb Major Weenies Kontrolle liegen: Zum einen das Problem, das hier f&uuml;r das Low-Tech Internet auszulegen. Fragen sie nicht den Major, wenn es darum geht, all die TABs und so weiter richtig zusammenzubasteln. Zum anderen ist REXX nicht C oder C++, also kommen sie mir nicht mit klassischem Zeug, wie "Nur ein Exit Punkt im einem Programm". So, das mu&szlig;te gesagt werden - was nun ? Jetzt m&uuml;ssen sie die Datei &ouml;ffnen. Die einfachste M&ouml;glichkeit, eine Datei in REXX zu ver&auml;ndern, ist nach Meinung des Majors ein einfaches LINEIN Kommando zu verwenden. Das sieht dann so aus:

rc = LineIn(Filename,,0)

In diesem Fall speichert REXX den R&uuml;ckgabewert in "rc". In diesem Beispiel sollte rc Null enthalten, wenn die Datei erfolgreich ge&ouml;ffnet werden konnte. Wenn sie in der REXX Online Hilfe nachschlagen, werden sie sehen, da&szlig; LINEIN das Format LineIn(name, line, count) hat. Beachten sie, da&szlig; ich "line" nicht verwendet habe. Da die Datei nicht ge&ouml;ffnet war, fing LineIn am Dateianfang an zu lesen und "count" bezeichnet die Anzahl der Zeilen, die ich einlesen wollte. Hier habe ich keine Zeilen gelesen, sondern nur die Datei ge&ouml;ffnet. Aye Bursche, schau in das Handbuch.

Was brauche ich noch ? Richtig! Irgendwo mu&szlig; ich mir merken, wie viele Worte und Zeilen ich eingelesen habe. Und wenn wir gerade dabei sind, k&ouml;nnten wir auch gleich feststellen, welches die l&auml;ngste Zeile ist. (Warum ? Weil wir dann wissen, wie wir den Zeilenumbruch am besten bewerkstelligen). Wir werden mit den drei Z&auml;hlern Counter, Allwords und Longline arbeiten und sie gleich mal auf Null setzen. Sie k&ouml;nnen das folgenderma&szlig;en machen:

Counter = 0; Allwords = 0; Longline = 0

Das Semikolon trennt jeweils die einzelnen Anweisungen voneinander.

Fassen wir also zusammen, was wir machen werden: Und so sieht das aus...
 * Eine Zeile einlesen
 * Die Worte in der Zeile z&auml;hlen
 * Die Zeilenl&auml;nge feststellen und merken, wenn es die l&auml;ngste bisher gefundene Zeile ist.

''' Do While Lines(Filename) &lt &gt 0          /* 'Lines' arbeitet bis keine Zeilen mehr da sind. */  Inp = Linein(Filename)               /* Inp enth&auml;lt den Inhalt der Zeile */ Y = Words(Inp)              	/* 'Words' liefert die Anzahl der Worte in der Zeile */ Z = Length(Inp)             	/* 'Length' stellt fest, wie lang die Zeile ist */ if Z > Longline then LongLine = Z   /* sie wissen schon... :-) */  Counter = Counter + 1                /* Z&auml;hler erh&ouml;hen und        */   Allwords = Allwords + Y      	/* die Anzahl der Worte in der Zeile speichern */ End /* do */ '''

Ok, wir haben alle diese Informationen zusammengesucht, was machen wir jetzt damit?

Nun, wir zeigen sie mit dem SAY Befehl an. Richtig, sie lesen meine Gedanken: Schlagen sie mal im Handbuch unter dem SAY Befehl nach. Einige Hinweise zum SAY Befehl: Das, was sie auf dem Bildschirm anzeigen m&ouml;chten, mu&szlig; in einfache (') oder doppelte (") Anf&uuml;hrungszeichen eingeschlossen werden, mit Ausnahme von definierten Variablen. Wenn sie also diese Befehle in ihr Programm schreiben:

''' One = "Willkommen zu" Two = "meinem" Three = "Alptraum" Say Eins Zwei Drei '''

Dann erscheint auf dem Bildschirm:

Willkommen zu meinem Alptraum Wenn sie Eins, Zwei oder Drei nicht definiert haben, bekommen sie:

Eins Zwei Drei

Wenn sie das hier vorher gemacht h&auml;tten:

''' Eins = 1 Zwei = 2 Drei = 3 Say Eins + Zwei + Drei ''' w&uuml;rde ihr Programm anzeigen... nein, das w&uuml;rde ihnen ja den ganzen Spa&szlig; verderben. Und so will ich das ganze verwenden: Zuerst m&uuml;ssen wir herausfinden, wie viele Seiten es gibt, indem wir die Anzahl der Zeilen durch 66 teilen. Sechundsechzig ist absolut willk&uuml;hrlich und ist eine Zahl, die ihren Ursprung weit in der Steinzeit hat, als Nadeldrucker &uuml;blicherweise nur 66 Zeilen auf einer Seite unterbringen konnten. Also definiere und berechne ich "Seite" so:

'''Seites = Trunc((Counter/66),1); If Seites = 0 Then Seites = Trunc((Counter/66),2)'''

Das "Trunc" Kommando sorgt f&uuml;r eine handhabbare Anzahl Nachkommastellen. Die Zahl auf zwei Stellen abzuschneiden, wenn weniger als eine Seite Daten vorhanden ist, ist eigentlich Overkill. Andererseits... der Major bevorzugt Feuerkraft...

Nachdem wir das herausgefunden haben, schreibe ich noch folgendes:

'''Say Filename 'enth&auml;lt 'Counter' Zeilen - das entspricht 'Seites' Seiten mit je 66 Zeilen.' Say 'Die l&auml;ngste Zeile in der Datei ist 'LongLine' Zeichen lang. Es gibt ' Say AllWords' Worte in der Datei.' '''

Sicher werden sie die Datei, die sie ge&ouml;ffnet haben, auch wieder schlie&szlig;en wollen, also werde ich ihnen eine kleine Aufgabe geben, mit der sie sich besch&auml;ftigen k&ouml;nnen, anstatt nach Dienst die Schiffsenergie im Holodeck zu verbraten. (Ach, und wir haben dieses gewisse Programm gefunden...) Schauen sie sich mal den STREAM Befehl an.

Wenn sie mir bis hierhin folgen konnten und CountWords mit der README Datei laufen lie&szlig;en, sollten sie ein Ergebnis bekommen haben, das etwa so aussieht:

'''README enth&auml;lt 851 Zeilen - das entspricht 12.8 Seiten mit je 66 Zeilen. Die l&auml;ngste Zeile in der Datei ist 74 Zeichen lang. Es gibt 3984 Worte in der Datei.''' Oh, hoppla, das ist der Captain, sie m&uuml;ssen mich entschuldigen. Sie haben es vermutlich geh&ouml;rt - dieser Fisch, der aus dem Aquarium sprang und den Replikator kurzgeschlossen hat so da&szlig; er jetzt, wenn er nach Earl Grey verlangt, etwas eher in der Art eines Duke of Earl bekommt.

Bis zum n&auml;chsten Mal bleibe ich ihr

Major Weenie

''Major Weenie ist Kent Rebman, ein Technischer Spezialist bei IBM. -ed''