Bestanden

Vaak zal het noodzakelijk zijn om bestanden te benaderen, enerzijds om daar informatie uit te halen, anderzijds om gegevens in op te slaan.
In Pascal wordt onderscheid gemaakt tussen het benaderen van bestanden om te lezen en om te schrijven.
Verder kent Pascal 3 verschillende soorten bestanden: tekst-bestanden, binaire-bestanden en ongedefinieerde bestanden.
De eerste soort gebruik je voor ascii-achtige bestanden. De tweede voor bestanden met een bepaalde structuur. De derde gebruik je voornamelijk voor bestandsbeheerachtige zaken, dus voor bestanden waar je van te voren niet weet hoe ze in elkaar zitten.
In deze paragraaf beperken we ons tot de eerste soort. Om met een tekstbestand te gaan werken moet je eerst weten of je naar een bestand gaat schrijven of uit een bestand gaat lezen.
De stappen die je moet volgen zijn de volgende:

1. Defienieer een tekst-bestand-variabele.
2. Ken de variabele toe aan een bestand.
3. Open het bestand om te lezen of schrijven.
4. Lees of schrijf naar het bestand (via de variabele).
5. Sluit het bestand.

ad 1.: Var tf: text;
hiermee definieer je een variabele tf van het type text, dat aangeeft dat je hiermee een ascii-bestand kan benaderen.
ad 2.: assign(tf,[pad]/[bestandsnaam]);
met de opdracht assign koppel je de text-variabele aan een (ascii-)bestand.
ad 3.: reset(tf); of rewrite(tf); met reset open je het bestand om te lezen, met rewrite open je het bestand om te schrijven. Als in het laatste geval het bestand al bestaat, dan wordt deze hiermee overschreven!
ad 4.: readln(tf,regel); of writeln(tf,regel);,
om resp. een regel tekst uit het bestand te lezen, dan wel een regel tekst naar het bestand te schrijven.
ad 5.: close(tf);
hiermee sluit je het bestand en geef je het weer vrij voor het besturingssysteem.

In het eerste voorbeeld gaan we een bestand openen en er drie regels tekst inzetten:

program p10_1;
var tf: text;
begin

  assign(tf,’c:\tp3\test.txt’);
  rewrite(tf);
  writeln(tf,’Dit is een test.’);
  writeln(tf);
  writeln(tf,’turbo pascal’);
  close(tf);
end.

Wanneer je nu met het kladblok test.txt opent, dan zie je dat er 3 regels tekst in staan, hoewel de tweede regel leeg is.

In het volgende voorbeeld gaan we test.txt uitlezen:

program p10_2;
type s80 = string[80];
var

  tf: text;
  regel: s80;
begin

  assign(tf,’c:\tp3\test.txt’);
  reset(tf);
  while not eof(tf) do
  begin
    readln(tf,regel);
    writeln(regel);
  end;
  close(tf);
end.

Omdat je vaak niet weet hoe groot een bestand is wil je het uitlezen tot het eind. Met de while not eof(tf)-constructie wordt dit bereikt. De eof-functie geeft de waarde true als je aan het einde van het bestand bent aangekomen (End Of File).

Wanneer je een bestand probeert te benaderen om te lezen en dit bestand bestaat niet, dan krijg je een foutmelding (run-time error).
Als je naar een bestand wilt schrijven dat al bestaat, is dat misschien niet wenselijk.
We zouden in beide gevallen een manier willen hebben om vooraf te kunnen controleren of een bestand al bestaat.
Dit kunnen we doen door de standaard-controle zoals ingebouwd door de compiler te omzeilen en deze controle zelf uit te voeren.
Dit gaat als volgt:

Direct voor het reset- of rewrite-statement zet je {$I-} neer om de compiler-controle uit te schakelen. Direct na een van statments zet je {$I+} neer om de compiler-controle weer te activeren.
Hierna lees je de ingebouwde virabele IOResult uit om te kijken of zich een fout heeft voorgedaan.

Laten we e.e.a. eens in een functie Bestaat implementeren:

function Bestaat(bn: s80): Boolean;
  var b: file;
begin

  assign(b,bn);
  {$I-}
    reset(b);
  {$I+}
  close(b);
  if IOResult = 0 then
  begin
    Bestaat := true;
    close(b);
  end
  else
    Bestaat := false;
end;

Nu kun je met de constructie if Bestaat(’test.txt’) then … kijken of test.txt in de huidige directory bestaat.
De regel var b: file; declareerd een ongedefinieerd bestand.

Oefeningen.

10.1
Schrijf een programma dat het aantal regels in een tekstbestand telt. Het programma moet om de naam van het bestand vragen. [Antwoord]

10.2
Schrijf een programma dat een Pascal-programma, waarvan de naam wordt gevraagd, voorziet van regelnummers. Het *.pas-bestand moet dezelfde naam behouden, maar nu met de extensie “.num”.
Met de functie copy([string-var],[start-pos],[aantal-kar] krijg je een nieuwe string die bestaat uit de deelstring van [string-var] vanaf positie [start-pos] over een lengte van [aantal-kar]. Zo levert copy(‘hallo’,1,3) de string ‘hal’ op. [Antwoord]

[Functies] <– –> [Recursie]