Konsolprogrammer - Start

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:

  1. Initialiser variable og indlæs konfiguration
  2. Udskriv lidt information om copyright
  3. Udfør dette i en løkke så længe programmet kører:
    1. Udskriv prompt og læs en kommando
    2. Parse den skrevne tekst og ekspander variable
    3. Udfør kommandoen
  4. 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)

User
Bruger #4063 @ 21.12.03 08:58
Hvor får man fat i Delphi? Er det noget man køber i en butik eller er det en form fpr freeware?
User
Bruger #8985 @ 22.01.07 20:47
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.
t