Standardfilerna Input och Output Standardfilerna Input och Output är textfiler av typen TEXT (som bara finns för filer). Innehållet är av typen Char och filerna är strukturerade i form av rader. En sådan fil kan läsas på vanligt sätt (med Emacs, more,... ) I standard Pascal skall programhuvudet, i program som använder in- och utmatning, innehålla PROGRAM test(input, Output); na kan omdirigeras med > och < (i UNIX) Ex. a.out < d.d > r.r Om det finns en fil d.d så kommer alla satser Read(variabellista) eller ReadLn(variabellista) läsas från filen d.d och om vi läser en variabel av typen Integer så sker konvertering automatiskt. Alla satser Write(variabellista) kommer att skrivas på filen r.r DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 1 / 24
... En fil är en strukturerad typ där alla poster är av samma typ. Man kan alltså skriva hela poster på filen! Alla filer utom Input och Output skall deklareras. Exempel på fildeklarationer: TYPE fil = FILE OF elementtyp; VAR minfil : fil; bilregister : FILE OF car; infil : FILE OF Integer; utfil : FILE OF studentuppgifter; txt : TEXT; {Fördefinierad filtyp} DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 2 / 24
... filtyper kan vara Interna: deklareras och öppnas med Rewrite(filnamn) Då blocket, där filen öppnades, lämnas går innehållet förlorat. Externa: Ordnad (efter insättningsordning) lista på sekundärminnet. na ges som parametrar i programhuvudet och deklareras i deklarationsdelen. öppnas för läsning med Reset(filnamn) och för skrivning med Rewrite(filnamn) DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 3 / 24
... vanlig utbyggnad för ökad dynamik Man kan också öppna filer på följande sätt (inte standard): För läsning: Reset(filnamn, fysisktnamn); Man får ett fel om filen inte finns. För skrivning: Rewrite(filnamn,fysisktNamn); Om filen redan finns så raderas den (töms på sitt innehåll). Exempel: Reset(minFil, filnamn.p ); na stängs då man lämnar det block där de öppnades eller då satsen Close(filnamn) exekveras (inte standard). DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 4 / 24
... fördefinierade procedurer och funktioner Fördefinierade procedurer och funktioner: Infil Utfil ReSet(f) Read(f, varlista) ReadLn(f, varlista) Eof(f) EoLn(f) ReWrite(f) Write(f, varlista) WriteLn(f, varlista) Öppna filen f för läsning läs från filen f Endast för textfil TRUE om sista item har lästs Endast för textfil Öppna filen f för skrivning Skriv på filen f Endast för textfil DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 5 / 24
... filbufferten Varje fil har ett minnesutrymme som rymmer exakt en post, minnesutrymmet kallas filbuffert. Man kan komma åt innehållet i filbufferten med f^ Write(f, p1); Är ekvivalent med: f^ := p1; {kopiera p1 till filbufferten} Put(f); {skriv buffertens innehåll på filen} Read(f, p1); Är ekvivalent med: p1 := f^; {kopiera filbufferten till p1} Get(f); {hämta nästa post till filbuff} DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 6 / 24
... filbufferten (2) Ex: Operativsystemet hanterar filerna i block (eller sidor) med en storlek av tex 2048 byte. Då man läser från filen är den minsta enheten ett block. Blocket läses till en area i primärminnet och från denna till pascals filbuffert. Filbufferten i pascal rymmer exakt en post av filtypen. Då en fil har öppnats har vi följande situation: fil OS buffert filbuffert programvariabel DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 7 / 24
... filbufferten (3) Ex: Operativsystemet hanterar filerna i block (eller sidor) med en storlek av tex 2048 byte. Då man läser från filen är den minsta enheten ett block. Blocket läses till en area i primärminnet och från denna till pascals filbuffert. Filbufferten i pascal rymmer exakt en post av filtypen. Då en fil har öppnats har vi följande situation: Och fil OS buffert filbuffert programvariabel efter att Read(fil, programvariabel); utförs DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 8 / 24
... fil med binärt innehåll (skrivning) PROGRAM storeintegers (Input, Output, intfile); TYPE integerfile = FILE OF Integer; VAR intfile : integerfile; ReWrite(intFile); WriteLn( Heltal: (sluta med negativt tal) ); REPEAT Read(intFile^); IF intfile^ >= 0 THEN Put(intFile); UNTIL intfile^ < 0; END. DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 9 / 24
... fil med binärt innehåll (läsning) PROGRAM sumint(input,output,intfile); TYPE integerfile = FILE OF Integer; VAR intfile : integerfile; sum, tmp : Integer; Reset(intFile); sum := 0; WHILE NOT EoF(intFile) DO Read(intFile, tmp); sum := sum + tmp Writeln( Summan=, sum) END. DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 10 / 24
... fil med läsbart innehåll (läsning) PROGRAM sumint(input, Output, intfile); VAR intfile : TEXT; sum, tmp : Integer; Reset(intFile); sum := 0; WHILE NOT EoF(intFile) DO Read(intFile, tmp); sum := sum + tmp Writeln( Summan=, sum) END. DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 11 / 24
... fil med läsbart innehåll (2) Vi kan skriva filen intfile med hjälp av Emacs. Problem: Om det efter sista heltalet finns ett radbyte eller något annat tecken kommer vi att försöka läsa ett heltal. Eftersom det man hittar på filen inte är en siffra kommer det att bli felavbrott! Lösning på problemet: PROGRAM sumint(input, Output, intfile); VAR tal, sum : Integer; intfile : TEXT; PROCEDURE skipuntilnextdigit(var afile : TEXT); IF NOT EoF(aFile) THEN IF NOT (afile^ IN [ 0.. 9 ]) THEN Get(aFile); skipuntilnextdigit(afile) DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 12 / 24
... fil med läsbart innehåll (3) Reset(intFile); sum := 0; skipuntilnextdigit(intfile); WHILE NOT EoF(intFile) DO Read(intFile, tmp); sum := sum + tmp; skipuntilnextdigit(intfile) Writeln( Summan=, sum) END. Get, Read och ReadLn läser även EoLn- markeringar. DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 13 / 24
... interna filer En intern fil fungerar som en extern fil förutom att innehållet försvinner då filen stängs (då blocket, där den öppnades, lämnas) samt att den inte skall specificeras som programparameter då ju programparametrarna utgör kommunikation mellan program och yttre enheter. Ex: Gör ett program som i en text byter alla förekomster av { mot (* och alla } mot * ). Spar texten på en intern fil med alla byten utförda. Överför sedan den interna filen till den externa filen. Utbytet görs genom satserna IF fromfile^= { THEN Write(toFile, (* ) ELSE IF fromfile^= } THEN Write(toFile, *) ) ELSE Write(toFile, fromfile^); Get(fromFile); DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 14 / 24
... interna filer (2) PROGRAM ex(fil); VAR fil, tmp: TEXT; PROCEDURE copyfile(var fromfile, tofile: TEXT); WHILE NOT EoF(fromFile) DO IF EoLN(fromFile) THEN WriteLn(toFile); IF fromfile^= { THEN Write(toFile, (* ) ELSE IF fromfile^= } THEN Write(toFile, *) ) ELSE Write(toFile, fromfile^); Get(fromFile) END ReSet(fil); ReWrite(tmp); copyfile(fil, tmp); ReSet(tmp); ReWrite(fil); copyfile(tmp, fil); END. DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 15 / 24
... dynamiska variabler / pekare Då dynamiska variabler skrivs till en fil spars även pekare. Då posterna läses från filen till programmet hamnar posterna inte säkert på samma ställe i minnet där de fanns innan de sparades på filen. Därför måste pekare alltid återställas efter inläsning från fil. Ex.: Då ett program terminerar spars en lista på en fil och då programmet återstartas läser man in elementen från filen och återskapar listan. DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 16 / 24
... dynamiska variabler / pekare (2) PROGRAM ex(input, output, elementfile); TYPE elementptr = ^element; element = RECORD info : < user defined >; next : elementptr; listptr = ^list; list = RECORD first : elementptr; elfile = FILE OF element; VAR thelist : listptr; listfile : elfile; < diverse procedurer och funktioner > thelist := newlist; readlistfromfile(thelist, listfile); run; savelistonfile(thelist, listfile); END. DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 17 / 24
... dynamiska variabler / pekare (3) PROCEDURE readlistfromfile(alist: listptr; VAR afile:elfile); PROCEDURE readel(var elptr: elementptr); IF EoF(aFile) THEN elptr := NIL ELSE NEW(elPtr); Read(aFile, elptr^); readel(elptr^.next) END ReSet(aFile); readel(alist^.first) DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 18 / 24
... dynamiska variabler / pekare (4) PROCEDURE savelistonfile(alist: listptr; VAR afile:elfile); VAR elptr: elementptr; elptr := alist^.first; WHILE elptr <> NIL DO Write(aFile, elptr^); elptr := elptr^.next END DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 19 / 24
... dynamiska variabler / pekare (5) PROCEDURE run; < fråga efter kommando > IF valid(kommando) THEN IF kommando = < första alt > THEN exec1stcommand ELSE... ELSE error; IF kommando <> exit THEN run; Eftersom pekarnas värden inte är meningsfulla efter inläsning kan man utelämna dessa då posterna spars. DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 20 / 24
... dynamiska variabler / pekare (6) TYPE elementptr = ^element; item = RECORD < user defined > element = RECORD info : item; next : elementptr; listptr = ^list; list = RECORD first : elementptr; elfile = FILE OF item; DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 21 / 24
... dynamiska variabler / pekare (7) PROCEDURE readlistfromfile(alist: listptr; VAR afile: elfile); PROCEDURE readel(var elptr: elementptr); IF EoF(aFile) THEN elptr := NIL ELSE NEW(elPtr); Read(aFile, elptr^.info); readel(elptr^.next) END ReSet(aFile); readel(alist^.first) DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 22 / 24
... dynamiska variabler / pekare (8) PROCEDURE savelistonfile(alist: listptr; VAR afile: elfile); PROCEDURE writeel(elptr:elementptr); IF elptr <> NIL THEN Write(aFile, elptr^.info); writeel(elptr^.next) END ReWrite(aFile); writeel(alist^.first); DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 23 / 24
... dynamiska variabler / pekare (9) Obs att elementens minnesutrymme måste avallokeras om programmet inte terminerar. PROCEDURE savelistonfile(alist: listptr; VAR afile: elfile); PROCEDURE writeel(elptr:elementptr); IF elptr <> NIL THEN Write(aFile, elptr^.info); writeel(elptr^.next); Dispose(elPtr) END ReWrite(aFile); writeel(alist^.first); DA2001 (Föreläsning 19) Datalogi 1 Hösten 2010 24 / 24