Ćwiczenie 2 Wczytywanie i zapisywanie do plików tekstowych 1. Wczytywanie z plików tekstowych. Wczytywanie z pliku tekstowego wymaga: a) skojarzenia zmiennej plikowej z plikiem procedura assignfile b) otwarcia pliku do odczytu procedura reset c) wczytania danych procedury read i readln d) zamknięcia pliku procedura closefile Oczywiście plik z którego mają być wczytywane dane musi istnieć, inaczej wystąpi błąd aplikacji. Przykład: program kon2; {$APPTYPE CONSOLE} uses SysUtils; var f:textfile; a,b,c:double; begin assignfile(f,'dane.txt');{powiązanie zmiennej plikowej z plikiem, parametry formalne nazwa zmiennej plikowej i nazwa pliku} reset(f);{otwarcie pliku do odczytu, ustawienie się na początku pliku, w zdecydowanej większości pozostałych funkcji i procedur związanych z operacjami na plikach nie wykorzystuje się nazwy pliku tylko odpowiadającej zmiennej plikowej} readln(f,a,b,c);{wczytanie zmiennych a,b,c z pierwszej linii pliku i przejście do nowej linii} closefile(f);//zamknięcie pliku powiązanego ze zmienną f end. 2. Zapisywanie do pliku tekstowego wymaga: a) skojarzenia zmiennej plikowej z plikiem procedura assignfile b) otwarcia pliku do zapisu procedury append i rewrite c) zapisania danych procedure write i writeln d) zamknięcia pliku procedura closefile Dla procedury append plik do którego zapisujemy musi już istnieć, dla procedury rewrite nie musi istnieć. Procedura rewrite spowoduje nadpisanie istniejącego już pliku bez pytania. Przykład: program kon2; {$APPTYPE CONSOLE} uses SysUtils; var f:textfile; a,b,c:double;
begin assignfile(f,'dane.txt'); reset(f); readln(f,a,b,c); closefile(f); asignfile(f,'wyniki.txt');{powiązanie pliku wyniki.txt ze zmienną plikową f} rewrite(f);{otwarcie pliku f (skojarzonego ze zmienną plikową f) do zapisu, jeżeli już istnieje taki plik to zostanie on w tym momencie nadpisany bez pytania,f będzie więc w tym momencie zawsze plikiem pustym} writeln(f,a);//zapisanie danej a w pierwszej linijce pliku f writeln(f,b);//zapisanie danej b w drugiej linijce pliku f writeln(f,c);//zapisanie danej c w trzeciej linijce pliku f closefile(f);//zamknięcie pliku powiązanego ze zmienną plikową f end. Załącznik AssignFile Wiąże (kojarzy) nazwę zewnętrznego pliku z nazwą zmiennej plikowej. metody do obsługi plików procedure AssignFile(var F; FileName: string); Wywołaj AssignFile aby zainicjalizować zmienną plikową. F jest zmienną plikową dowolnego typu. FileName jest wyrażeniem typu łańcuch znaków (string) lub wyrażeniem typu PChar jeżeli rozszerzona składnia jest włączona. Po wywołaniu AssignFile, F jest powiązane z plikiem zewnętrznym do czasu zamknięcia F. Wszystkie późniejsze operacje (po wywołaniu AssignFile, a nie zamknięciu pliku) na zmiennej plikowej F są operacjami na pliku zewnętrznym nazwanym przez FileName. Jeżeli parametr FileName jest pusty, AssignFile wiąże F ze standardowym plikiem wejścia lub wyjścia. Jeżeli powiązana jest pusta nazwa pliku, to po wywołaniu Reset(f), F odnosi się do standardowego pliku wejścia, a po wywołaniu Rewrite(F), F odnosi się do standardowego pliku wyjścia. Nie używaj AssignFile na zmiennej plikowej która już jest otwarta.
Reset Otwiera istniejący plik. procedury wejścia/wyjścia (I/O routines) procedure Reset(var F [: File; RecSize: Word ] ); Reset otwiera istniejący plik zewnętrzny o nazwie skojarzonej z F. Wystąpi błąd jeżeli nie istnieje zewnętrzny plik o podanej nazwie. Jeżeli F jest już otwarty, to jest przez procedurę uprzednio zamykany i wtedy znowu otwierany. Pozycja w pliku ustaiwana jest na początku pliku. F jest zmienną dowolnego typu powiązanego z zewnętrznym plikiem za pomocą procedury AssignFile. RecSize jest wyrażeniem opcjonalnym, które może zostać określone tylko jeżeli F jest plikiem nietypowanym. Jeżeli F jest plikiem nie typowanym RecSize określa wielkość rokordu używanego w transferach danych. Jeżeli RecSize zostanie w takim przypadku ominięte, przyjmowana jest jego domyślna wartość 128 bajtów. Jeżeli F jest powiązany z pustą nazwą, taką jak AssignFile(F, ), to po wywołaniu Reset, F odnosi się do standardowego pliku wejściowego. Jeżeli F jest plikiem tekstowym, F staje się plikiem tylko do odczytu. Po wywołaniu Reset, Eof(F) ma wartość True jeżeli plik jest pusty, w innym przypadku Eof(f) ma wartość False. Read Read wczytuje dane z pliku. metody plików tekstowych Pliki typowane: procedure Read(F, V1 [, V2,...,Vn ] ); Pliki tekstowe: procedure Read( [ var F: Text; ] V1 [, V2,...,Vn ] );
Procedura Read może być użyta na następujące sposoby: - dla plików typowanych, czyta komponent pliku do zmiennej - dla plików tekstowych, czyta jedną lub więcej wartości do jednej lub więcej zmiennych Dla zmiennych typu string: - Read czyta wszystkie znaki do końca (ale z wyłączeniem) znaku końca linii lub dopóki Eof(F) nie staje się True; nie przeskakuje do następnej linii po odczytaniu. Jeżeli wynikowy string jets dłuższy niż maksymalna długość zadeklarowanej zmiennej typu string, wynik jest obcinany (tak żeby się zmieścił do zmiennej). - Po pierwszym Read, każdy następny Read widzi znak końca linii i zwraca string o zerowej długości. - Wykorzystanie wielokrotnych Readln powoduje sukcesywne wczytywanie wartości zmiennych typu string. Dla zmiennych typu char: - Read czyta jeden znak z pliku i przypisuje go do zmiennej. Jeżeli Eof(F) ma wartość True przed wykonaniem Read, do zmiennej przypisywana jest wartość Chr(26) (tj. znak Ctrl+Z). Dla zmiennych typu całkowitego (np. integer) lub zmiennej typu zmiennoprzecinkowego (np. double): - Read opuszcza spacje, tabulatory i znaki końca linii poprzedzające liczbowy łańcuch znaków. - Jeżeli liczbowy łańcuch znaków nie ma spodziewanego formatu, występuje błąd I/O; w innym przypadku, wartość jest przypisywana do zmiennej. - Następny Read zaczyna od spacji, tabulatora lub znaku końca linii który zakończył (poprzedni) liczbowy łańcuch znaków. CloseFile Kończy powiązanie pomiędzy zmienną plikową i zewnętrznym plikiem. metody obsługi plików procedure CloseFile(var F); F jest zmienną plikową dowolnego typu otwartego za pomocą Reset, Rewrite lub Append. Zewnętrzny plik powiązany z F jest kompletnie aktualizowany i później zamykany, co powoduje zwolnienie uchwytu do pliku i pozwala na jego ponowne wykorzystanie. Rewrite Tworzy nowy plik i go otwiera.
metody I/O procedure Rewrite(var F: File [; Recsize: Word ] ); Rewrite tworzy nowy zewnętrzny plik z nazwą powiązaną ze zmienną F. F jest zmienną plikową dowolnego typu powiązaną z zewnętrznym plikiem przy użyciu AssignFile. RecSize jest opcjonalnym wyrażeniem, które może być określone tylko jeżeli F nie jest plikiem typowanym. Jeżeli F nie jest plikiem typowanym, RecSize określa wielkosć rekordu używanego do transferów danych. Jeżeli RecSize jest opuszczony, przyjmowana jest domyślna wartość rozmiaru rekordu tj. 128 bajtów. Jeżeli zewnętrzny plik o tej samej nazwie już istnieje, to jest kasowany i nowy pusty plik jest tworzony na jego miejsce. Jeżeli F jest już otwarty, to jest najpierw zamykany i wtedy ponownie tworzony. Pozycja pliku jest ustawiana na początek pustego pliku. Jeżeli F miał pustą nazwę, taką jak AssignFile(F, ), to po wywołaniu Rewrite, F odnosi się do standardowego pliku wyjściowego. Jeżeli F jest plikiem tekstowym, F zostaje otwarty w trybie tylko do zapisu. Po wywołaniu Rewrite, Eof(F) jest zawsze True. Append Przygotowuje istniejący plik do dodawania tekstu na koniec. metody I/O procedure Append(var F: Text); Wywołaj Append aby zapewnić otwarcie pliku tylko do zapisu z wskaźnikiem ustawionym na końcu pliku. F jest zmienną plikową i musi być powiązana z zewnętrznym plikiem poprzez AssignFile. Jeżeli zewnętrzny plik o podanej nazwie nie istnieje, wystąpi błąd. Jeżeli F jest już otwarty, to zostaje zamknięty i ponownie otwarty. Aktualna pozycja wskaźnika w pliku jest ustawiana na koniec pliku.
Jeżeli wystąpi znak Ctrl+Z (ASCII 26) w ostatnim 128 bajtowym bloku pliku, aktualna pozycja wskaźnika w pliku jest ustawiana tak że następny znak dodawany do pliku nadpisuje Ctrl+Z w bloku. W ten sposób tekst może być dopisywany do pliku który kończy się znakiem Ctrl+Z. Jeżeli F nie miał przypisanej nazwy, to po wywołaniu Append, F odnosi się do standardowego pliku wyjścia. Write (dla plików tekstowych) Zapisuje do pliku tekstowego. metody plików tekstowych procedure Write( [var F: Text; ] P1 [, P2,..., Pn] ); Write zapisuje jedną lub więcej wartości do pliku tekstowego. F, jeżeli jest określone, jest zmienną plikową pliku tekstowego. Jeżeli F jest opuszczone, to używana jest standardowa zmienna plikowa Output. Każda P jest parametrem write. Każdy parametr write dodaje wyjściowe wyrażenie którego wartość ma być zapisana do pliku. Parametr write może także zawierać specyfikacje szerokości pola i liczby miejsc po przecinku. Każde wyrażenie wyjściowe musi być typu Char, jednego typów całkowitych (Integer, Byte, Shortint, Word, Longint, Cardinal), jednego z typów zmiennoprzecinkowych (Single, Real, Double, Extended, Currency), jednego z typów zmiennej łańcuchowej (PChar, AnsiString, ShortString), spakowanym string lub jednym z typów logicznych (Boolean, Bool). Parametr write ma formę OutExpr [: MinWidth [: DecPlaces ] ] gdzie OutExpr jest wyrażeniem wyjściowym. MinWidth i DecPlaces są wyrażeniami typu całkowitego. MinWidth określa minimalną szerokość pola, która musi być większa od 0. Dokładnie MinWidth znaków jest zapisanych (z użyciem poprzedzających spacji jeżeli to konieczne) chyba że OutExprma wartość która musi być reprezentowana w więcej niż MinWidth znakach. W takim przypadku, zapisywana jest wystarczająca liczba znaków tak żeby poprawnie reprezentować wartość OutExpr. Podobnie, jeżeli wartość MinWidth jest opuszczona, to wymagana liczba znakó jest zapisywana dla reprezentacji OutExpr. DecPlaces określa liczbę miejsc po przecinku w reprezentacji jednego z typów rzeczywistych. Wartośc DecPlaces może być określona tylko jeżeli OutExpr jest zmienną jednego z typów rzeczywistych i MinWidth również jest określona. Jeżeli MinWidth jest określona, to wartość DecPlaces musi być większa bądź równa 0.
Write z wartością typu znakowego: Jeżeli MinWidth jest opuszczony, to wartość znaku OutExpr jest zapisywana do pliku. W innym przypadku zapisywane jest do pliku MinWidth 1 spacji a potem OutExpr. Write z wartością całkowitą (typu całkowitego): Jeżeli MinWidth jest opuszczony, dzisiętna reprezentacja OutExpr jest zapisywana do pliku bez poprzedzających spacji. Jeżeli MinWidth jest określony i jego wartość jest większa niż długość łańcucha cyfr zmiennej, przed liczbą zapisywane są spacje tak by szerokość pola była dokładnie MinWidth. Write z wartościami rzeczywistymi (typu rzeczywistego): Jeżeli OutExpr jest jednego z typó rzeczywistych, jego dzisiętna reprezentacja jest zapisywana do pliku. Format reprezentacji zależy od obecności lub nieobecności DecPlaces. Jeżeli parametr DecPlaces jest pominięty (lub gdy występuje ale ma wartość ujemną), zapisywany jest zmiennoprzecinkowy łańcuch znaków. Jeżeli MinWidth też jest pominięty, przyjmowana jest domyślna wartość MinWidth tj. 17; w innym przypadku, jeżeli MinWidth ma wartość mniejszą niż 8, przyjmuje się że ma wartość 8. Format zmiennoprzecinkowego łańcucha znaków jest następujący: [ - ] <digit>. <decimals> E [ + - ] <exponent> Następująca tabela pokazuje komponenty wyjściowego łańcucha znaków. Komponent Znaczenie [ - ] " " lub "-" w zależności od znaku OutExpr <digit> pojedyncza cyfra, 0 tylko jeżeli OutExpr ma wartość 0 <decimals> łańcuch cyfr o długości MinWidth-7 (ale najwyżej 10) znaków E E pisane dużą literą [ + - ] zależnie od znaku wykładnika <exponent> dwucyfrowy wykłądnik Jeżeli parametr DecPlaces wystąpił, zapisywany jest łańcuch cyfr z ustalonym połóżeniem przecinka (kropki). Jeżeli DecPlaces jest większy niż 11, to przyjmuje się że ma wartość 11. Format takiego łańcucha jest następujący: [ <blanks> ] [ - ] <digits> [. <decimals> ] Tabela przedstawia znaczenie wykorzystanych powyżej symboli: Komponent Znaczenie [ <blanks> ] spacje, tyle żeby spełniony był warunek wynikający z MinWidth [ - ] jeżeli wyrażenie jest ujemne <digits> Przynajmniej jedna cyfra, ale bez poprzedzających ją zer [. <decimals> ] liczby po przecinku jeżeli DecPlaces >0
Write ze wartością typu łańcuchowego: Jeżeli MinWidth jest pominięty, wartość łańcucha OutExpr jest zapisywana do pliku bez poprzedzających spacji. Jeżeli MinWidth jest określony, a jego wartość większa niż OutExpr, to dopisywana jest z przodu odpowiednia ilość spacji tak by szerokość pola miała wartość MinWidth. Write z wartością typu spakowany łańcuch znaków: Jeżeli OutExpr jest spakowanym łańcuchem znaków, efekt jest taki sam jak przy zapisywaniu łańcucha znakówktórego długość jest liczbą elementów w spakowanym łańcuchu znaków. Write z wartością typu logicznego: Jeżeli OutExpr jest typu logicznego, to efekt jest taki sam jak przy zapisywaniu łąńcuchów znaków True lub False, zależnie od wartości OutExpr. Uwaga: Przy używaniu Write plik musi być otwarty do zapisu.