11
Tags:
delphi
Skrevet af
Bruger #58
@ 13.10.2002
Konsolprogrammer part 1 - Start med konsolprogrammer
I denne artikel vil du lære hvordan man laver
konsolprogrammer, som også er kendt som text-mode programmer eller, fejlagtigt,
DOS-programmer. (Konsol-programmer er ægte 32-bit Windows programmer selvom de
kører i et tekstvindue, og har i og for sig intet med DOS at gøre.) Jeg vil
desuden vise hvordan man kan lave en simpel kommandofortolker i stil med
command.com eller cmd.exe.
Starten af et konsolprogram
I Delphi vælger du File -> New -> Other, og vælger så ”Console application”.
Hvis du ikke har denne mulighed i din version
af Delphi skal du lave et nyt program, og så gå op i View menuen, vælge Project
Manager og så fjerne din Form fra den! Så skal du vælge View -> Project Source.
Dit kodevindue skal nu indeholde følgende kode:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
begin
end.
Afhængig af din Delphi version står der måske
en kommentar mellem
begin og
end, den kan du bare slette. Hvis
der står mere end
SysUtils i
uses skal du slette det.
Anden linie (
{$APPTYPE CONSOLE}) er
meget vigtig, det er et såkaldt compiler-direktiv som fortæller Delphi at vi er
ved at lave et konsol-program. Læg også mærke til at der er et punktum efter
den sidste
end, i stedet for et semikolon som normalt. Det er for at
markere at filen slutter her, ligesom mange tidsskrifter afslutter deres
artikler med en stor fed prik eller et lille logo bag ved sidste linie.
Prøv nu at køre programmet, der skulle så gerne
komme et sort konsol-vindue som lukker igen med det samme. Hvis der ikke gør
det så tjek at din kode én gang til. :)
Få den til at skrive noget
Ok! Nu skal vi have den til at skrive noget på skærmen. Men
lad os først lige sørge for at den ikke lukker øjeblikkeligt efter at den er
startet, så vi kan nå at se hvad den skriver! Skriv følgende linie mellem
begin
end
end:
Readln;
Så prøv at køre programmer igen. Nu skulle
vinduet gerne blive stående på skærmen. Hvis du så trykker Enter vil det lukke.
Readln er en standard input/output funktion i Delphi som læser en linie
fra en tekstfil eller, som her, fra konsollen. (Teknisk set
er konsollen
faktisk en tekstfil.) Hvis du prøver at skrive nogen andre tegn end Enter så
vil de bare komme frem på skærmen. Senere vil vi se på hvordan vi kan putte den
tekst man skriver, ind i en variabel.
Men nu skal vi have den til at skrive til
skærmen. Prøv at sætte den her linie ind oven over din
Readln linie:
Writeln(’Hejsa’);
Så kør dit program. Nu skriver den ”Hejsa”
øverst i konsolvinduet og venter igen på dit tastetryk.
Writeln er en
standard i/o funktion ligesom
Readln er det. Den skriver en linie til en
tekstfil eller konsollen. Læg mærke til at hvis du bruger æøÅ i din tekst
bliver det vist forkert, det skyldes at Windows bruger et andet tegnsæt i
konsol-programmer end i GUI (grafiske) programmer. Det er der desværre ikke
noget at gøre ved umiddelbart. Jeg vil komme med en mulig løsning på det problem i en senere artikel.
Læsning af input
Nu skal vi se hvordan man får sit program til at læse hvad
brugeren skriver. For at gøre dette skal vi først bruge en variabel at gemme inputtet
i. Oven over din
begin linie skriver du følgende:
var
Alder: integer;
Nu har vi en variabel til at gemme den indlæste
værdi i. Ret koden mellem din
begin end
end så den ser således
ud:
begin
Write('Hejsa, hvor gammel er du? ');
Readln(Alder);
if alder <= 10 then
Writeln('Er du ikke lidt ung af en programmør at være?')
else
Writeln('Ok, du er altså ', alder, ' år gammel! :)');
Readln;
end.
Her ser vi også en nu funktion,
Write.
Den fungerer nøjagtig ligesom
Writeln, bortset fra at den ikke udskriver
et linieskift bagefter.
Readln(Alder)
instruerer Delphi om at den skal læse en linie og forsøge at putte resultatet
ind i
Alder variablen. Siden
Alder er integer er det kun tilladt
at skrive tal, selvom intet forhindrer en i at gøre andet. Hvis man skriver
noget ugyldigt kommer der bare en fejl og programmet lukker.
Læg mærke til hvordan den 7. linie er skrevet.
Der er først en string, så komma for næste argument, så navnet på
Alder
variablen og så en string i næste argument igen. Det instruerer Delphi i at de
tre ting skal skrives på samme linie i den rækkefølge. Læg også mærke til at vi
kan udskrive et tal uden at bruge IntToStr() eller lignende funktioner! Den
klarer Delphi automatisk. De to ting gør
Write og
Writeln ret
specielle i forhold til de fleste andre funktioner.
Read og
Readln
har lignende funktioner så man kan indlæse flere værdier med et kald.
Nu kan du prøve at skrive nogen små programmer
til at lave simple ting, prøv f.eks. at lave et program som indlæser to tal og
udskriver resultatet af de to tal plusset. Bagefter prøv at lave et program som
indlæser tal indtil man skriver 0 og udskriver dem alle sammen plusset! Du kan
selv finde på mere :)
En simpel kommandofortolker
Nu hvor vi har de grundlæggende ting på plads kan vi prøve
at lave et mere avanceret program, nemlig en kommandofortolker! For at tage
lidt teori først vil vi se på hvordan sådan en normalt er opbygget:
- Initialiser variable og indlæs konfiguration
- Udskriv lidt information om copyright
- Udfør dette i en løkke så længe programmet kører:
- Udskriv prompt og læs en kommando
- Parse den skrevne tekst og ekspander variable
- Udfør kommandoen
- Ryd op og gem opsætning
Vi vil selvfølgelig ikke lave alle tingene, da det vil blive
alt for stort og uoverskueligt for en artikel. I stedet kan vi starte med det
mest simple: En løkke som læser en kommando og derefter udfører den. For at
gøre det simpelt for os selv kan vi starte med to kommandoer:
info og
quit.
Info skal vise lidt information om programmet og
quit afslutter
det.
Lav først et nyt konsolprogram ligesom før. Vi
starter med at lave en variabel til at gemme den indtastede kommando i. Vi
laver også en variabel til at gemme om programmet stadig kører.
var
kommando: string;
koerer: Boolean;
Så laver vi en løkke som kører så længe
koerer
er sand, mens vi sørger for at
koerer er sand før vi går ind i løkken.
(Hvis vi ikke tildeler den en værdi er det udefineret hvad værdien er, og den
kan lige så godt være sand som falsk.)
begin
koerer := True;
while koerer do
begin
end;
end.
Inde i
while-løkken skriver vi først noget kode til at læse en kommando:
Write('> ');
Readln(kommando);
kommando := Trim(kommando);
Den første linie udskriver en standard-prompt
(klar-besked, ”jeg kan modtage kommandoer nu”). Derefter indlæser vi en linie
til
kommando variablen. Den sidste linie fjerner evt. mellemrum i
starten og slutningen af den indtastede kommando. (Det ville virke lidt fjollet
hvis den forstod ”quit” men ikke ”quit ” (altså med et mellemrum bagved).)
Hvis du kører programmet nu vil der ikke være
nogen pæn måde at lukke det på, så lad os skynde os at lave en
quit
kommando. Det kan vi gøre sådan her:
if kommando = 'quit' then
begin
koerer := False;
end;
Den kode skal ind under koden som læser en
kommando. Prøv at køre dit program nu. Hvis du skriver
quit skulle det
gerne afslutte og hvis du skriver noget som helst andet vil der ikke ske noget
som helst. Måske burde man gøre så den giver en fejl hvis den ikke kender
kommandoen?
Vi kan starte med at springe al koden til at
udføre kommandoen over hvis man slet ikke har skrevet nogen kommando. Det er
meget nemt, vi sætter en stor
if
uden om det hele, og i den
if
som tjekker for kommando kan vi så lave en
else
der udskriver en fejl. Så ser hele koden sådan her ud:
var
kommando: string;
koerer: Boolean;
begin
koerer := True;
while koerer do
begin
Write('> ');
Readln(kommando);
kommando := Trim(kommando);
if kommando <> '' then
begin
if kommando = 'quit' then
begin
koerer := False;
end
else
begin
Writeln('Ukendt kommando: "', kommando, '"');
end;
end;
end;
end.
Prøv selv at tilføje en
info kommando
som udskriver dit navn og programmets version. En
help kommando er også
altid på sin plads. En kørsel af programmet kan så f.eks. se således ud:
Mere avancerede kommandoer
Nu vil vi prøve at tilføje en
echo kommando. Den
bruges til at udskrive en tekst til skærmen. I sig selv er den måske ikke så
brugbar, men hvis man engang skal have sin kommandofortolker til at udføre
scripts (batch-filer) er den god at have.
Echo er specielt interessant fordi den
tager en parameter (den tekst der skal vises), mens den samtidig er utrolig
simpel. Fordi
echo skal have parametre kan vi ikke bare tjekke om
kommando
= ’echo’ fordi den vil kun
matche når der ikke er nogen parameter på. Derfor bruger vi Delphis
Copy()
funktion til at tjekke om de første 4 tegn i den skrevne tekst er ’echo’.
Derefter kan vi igen bruge
Copy() til at trække alt efter de første 4
tegn ud og udskrive det.
Koden til det kan se således ud:
else if Copy(kommando, 1, 4) = 'echo' then
begin
Writeln(Trim(Copy(kommando, 5, Length(kommando) - 4)));
end
Koden skal sættes ind under koden for
quit
kommandoen. Bemærk at der
ikke skal være semikolon efter
end i
koden for
echo fordi der kommer en
else
efter den.
Kør programmet igen og prøv kommandoer som
f.eks. ”
echo foobar” og ”
echo lang tekst med mellemrum”, men
prøv også f.eks. ”
echoen tekst”
(altså uden mellemrum efter
echo.) Det vil (modsat hvad man ville
forvente) også virke! Vi skal altså have en måde at sørge for at der altid er
mellemrum efter kommandoer. Koden til at trække parametrene ud er heller ikke
alt for pæn, det må kunne gøres bedre.
Der vil også være andre fordele ved at finde
kommandoer og parametre på en general måde: Det vil blive langt lettere at
tilføje nye kommandoer, og programmet risikerer ikke at blive sløvet ved
ekstremt lange kæder af if-sætninger når det får flere kommandoer.
Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.
Del også gerne artiklen med dine Facebook venner:
Kommentarer (2)
Hvor får man fat i Delphi? Er det noget man køber i en butik eller er det en form fpr freeware?
Enten køber du det, eller også downloader du en trial. Søg på google efter fx. Delphi eller Borland.
Dejlig artikel forresten, selvom jeg desværre ikke længere koder Delphi. Men det er jo ikke din fejl
Du skal være
logget ind for at skrive en kommentar.