YAZI DOSYALARI
(YAZI KÜTÜKLERİ, TEXT FILES)
Şimdiye kadar yazdığımız programlarda
değişkenlere değer atamak için klavyeyi kullandık. Girdiğimiz veriler, program
kapanınca yok oldu. Oysa, bir çok uygulamada aynı verileri defalarca kullanmak
gerekir. Örneğin, bir kentte Su İşleri Dairesi’nin 30.000 abonesi var olsun.
Aylık fatura göndermek için, her abonenin abone numarası, adı, adresi,
tükettiği su miktarı ve ödeyeceği su bedeli gibi bilgilerin yazılması gerekir. Her seferinde bunları
yeniden girmek zor ve zaman alıcı bir iştir. Bu veriler arasında değişecek
olanlar tüketilen su miktarı ve su bedelidir. Dolayısyla, değişmeden kalan
öteki verilerin bir kayıt ortamında saklanarak, her ay kullanılması kolaylık,
doğruluk, hız ve ekonomi sağlar.
Standart Pascal sıralı erişimli dosya
yaratır. Bunlar da kendi içinde ikiye ayrılabilir: TEXT dosyaları ve Binary
Dosyalar. Bu bölümde TEXT Dosyalarını inceleyeceğiz.
TEXT, Pascal’da bir temel
veri türüdür. Düz yazı (metin) anlamına gelir. Bir TEXT dosyasını, satırlara ayrılmış,
char türünden bir array olarak düşünebiliriz. Dosyalar, magnetik disk, teyp, CD
gibi bir kayıt ortamı üzerinde saklanır, ama başka bir araca da bağlı
olabilirler. Örneğin Pascal'da INPUT klavyeye bağlı bir yazı dosyası ve OUTPUT ekrana bağlı bir yazı dosyasıdır.
Standart Pascal‘daki INPUT
ve OUTPUT text dosyaları program çalışırken daima açık olur ve özel bir işleme
gerek kalmadan kullanılabilirler. Ama başka dosyalar için bir bildirim
gereklidir.
TEXT Dosyası
Bildirimi
Text bir veri tipi olduğu için,
onu temsil eden değişkenleri, Pascal’da değişken bildirimi yöntemiyle
tanımlayabiliriz. Örneğin, Mektup
adlı bir text değişkenini bildirmek için,
var
Dosya_Adı : text;
bildirimi yapılır.
Bilindiği gibi farklı veri
tipleri ile farklı işlemler yapılır. Örneğin, char, real,
boolean veri tiplerini temsil eden değişkenlerle yapılabilen
işlemler birbirlerinden farklıdır ve herbiri kendi veri tipine özgü işleri
yapar. Aynı olgu, TEXT tipini temsil eden değişkenler için de geçerlidir. O
halde, text tipinden bir değişken ile yapulabilecek işler, bir metin (düz yazı)
ile yapılabilen işler olmalıdır.
İstediğimiz kadar ardışık
karakterler ekleyerek istediğimiz uzunlıkta bir yazı yazabiliriz. Yazının
sonunu ve satırlarını belirtebiliriz.
Öyleyse, TEXT türünden olan Mektup
değişkeni üzerinde de aynı işleri yapabilmeliyiz.
Anlamayı kolaylaştırmak
için, bir kelime işlemci ile bir yazı yazdığımızı düşünelim. Ortaya çıkan metni
bir ad vererek diske kaydettiğimizde bir TEXT dosyası yaratmış oluruz. Yazının
son karakterinden sonra, dosyanın sona erdiğini belirten bir simgeyi sistem
kendiliğinden koyar. İngilizce „End Of File“ deyiminin kısaltması olan bu
simgeyi <eof> ya da EOF ile göstereceğiz. Benzer olarak Enter (Giriş)
tuşuna her basışta satır sona erer ve yeni bir satıra geçilir. Enter’e basıldığında, satırın sona erdiğini
belirten bir simgeyi sistem kendiliğinden o satırın sonuna yazar. İngilizcede
„End Of Line“ deyiminin kısaltması olan bu simgeyi <eoln> ya da EOLN ile
göstereceğiz.
Bir kelime işlemcinin yaptığı
bu işleri Pascal’ın text dosyaları aynen yapar. Buna ek olarak, text (yazı)
içine sayısal verileri girebiliriz. Pascal, sayısal verileri karakter dizisine
dönüştürerek text’e yazar. Bunu okurken de ters işlem yaparak, karakter dizisi
olarak kaydettiği sayıyı yeniden sayı biçimine dönüştürür. Bunu nasıl yaptığını
biraz sonra göreceğiz.
Dosya yaratma, dosyaya
yazma ve dosyada yazılı olanları okuma eylemleri, farklı Pascal sistemlerinde
farklı deyimlerle yapılmaktadır. Ama, esas olarak yapılan işlem hepsinde
aynıdır. Bu nedenle, önce Standart Pascal’ın deyimlerini, sonra da Turbo
Pascal’ın deyimlerini vereceğiz.
Standart Pascal’da text
dosyaları ile ilgili işlemler, sıralı erişimli binary dosyalardaki gibidir.
Text dosyasının bileşenleri karakter tipinden olduğu için, ana bellekteki dosya
tamponu bir karakter tutar.
Örnek : Standart Pascal’da aşağıdaki program Mesaj adlı bir text dosyası
yaratır. Kullanıcı ‚*’ karakterini girince dosyaya yazma işi biter.
Program text01 (input,
output);
Var
Ch : char;
Mesaj : Tezt;
Begin
Rewrite
(Mesaj);
Repeat
Read
(ch) ;
Mesaj^ := ch;
Put
(Mesaj)
Until ch == ‘*’ ;
Close(Mesaj)
End.
Örnek
PROGRAM Text02 (input,
output);
var
a : Integer;
b : Real;
Ch : Char;
Filex : Text;
BEGIN
a:= 12 ;
b := 7.35 ;
REWRITE(Filex);
Write(Filex, 'a =', a:3);
Write(Filex, 'b =', b:6:1);
Write(Filex,2.0*b + 1.5:6:1);
writeln;
reset(Filex);
While not EOF(Filex) Do
Begin
While not EOLN(Filex) do
Begin
read(Filex,Ch);
write(Ch);
end;
end;
END.
Örnek
PROGRAM Text03 (input,
output);
var
Ch : Char;
Kutuk : Text;
PROCEDURE YAZIGIR(var KutukF :Text);
Const
Satir = '\';
Son = '*';
BEGIN
Rewrite(KutukF);
Writeln('Bu program TEXT kutugune bir
ornektir ');
writeln('Metin giriniz.Satir sonunu
"\" ,metin sonunu "*" ile gosteriniz');
Repeat
Read(Ch);
If
ch = '\' then
writeln(KutukF);
ELSE
Write(KutukF,Ch)
Until
Ch
= Son;
END;
PROCEDURE YAZIOKU(var KutukF:Text);
Begin
Reset(KutukF);
While NOT EOF(KutukF) Do
Begin
{Satir Oku ve Yaz}
writeln;
While NOT EOLN(KutukF) and not EOF(KutukF) do
Begin {Harf oku ve yaz}
Read(KutukF,Ch);
Write(Ch);
End; {Harf okuma ve yazma}
Writeln;
Readln(KutukF);
End;
{Satir okuma ve yazma}
End;
Begin
YAZIGIR(Kutuk);
YAZIOKU(Kutuk);
End.
Rewrite (Mesaj)
Standart Pascal’da bir dosya ya yazılmak
ya da okunmak için açılır. Hangi amaçla açıldığı, dosyanın
açılış deyimiyle belirtilir.
Dosyanın Yazılmak İçin
Açılması
Rewrite(Out_File) Out_File adlı dosyayı yazmak için
hazırlar. Dosyayı açar ve dosya işaretçisi dosyanın ilk bileşenini gösterir. Bu
adla bir dosya yoksa, açarken onu yaratır. Bu adla bir dosya varsa, onun
içeriğini tamamen siler ve yeni bir dosya açıyormuş gibi, ilk bileşenini
göstermeye başlar. Bu işlemle silinen dosyanın içeriği bir daha bulunamaz.
Dolayısıyla, var olan dosyaları yanlışlıkla silmemek için, Rewrite deyiminin
önüne bir denetim procedürü konulmalıdır.
Rewrite(Dosya_Adı);
Deyimi dosyayı yazılmak
üzere açar.
Reset(In_File) In_File adlı
dosyayı okunmak üzere hazırlar; yani dosyayı okunmak üzere açar, dosya
işaretcisi dosyanın ilk bileşenini işaret eder. Eğer dosya boşsa ya da bu adla bir dosya yoksa, EOF(In_File)
fonksiyonu TRUE değerini, değilse FALSE değerini alır.
Standart Pascal'da VERI,
değişkenine bir değer atamaya gerek kalmaz; bir geçici iç dosya olarak
kullanılabilir. Bu tür kütükler programın sonunda otomatik olarak
silinir. Turbo Pascal iç kütükleri kabul etmez. Turbo Pascal'da text tipindeki
(ya da ilerde göreceğimiz diğer kütük tipindeki) her değişkene bir değer atamak
gerekir. Bu değer, fiziksel kayıt ortamına kaydedilecek dosyaya verilecek DOS
adıdır. belli bir DOS kütüğü adına bağlı olmalıdır. Bu bağlantı assign deyim
ile yapılır:
assign(<Kütük değişkeni>, <DOS kütük adı>);
Burada <DOS kütük
adı> bir string‘dir; dolayısıyla (‘ ‘) simgeleri arasına yazılır. Örnek
Assign(VERI,
'sayilar.dat');
deyimi, VERI adlı kütük değişkenini,
sayilar.dat adlı DOS kütüğüne eşler. Bu eşleme, VERI değişkenine ‘Sayilar.dat’
değerinin atanması demektir. Gerekirse, fiziksel ortamın yerini belirleyen “DOS
adresi” de verilebilir. Örneğin, 'a:\pas\'sayilar.dat'. Bu atamadan sonra, VERI
değişkeni kullanılarak yapılan her işlem, aslında sayilar.dat kütüğüne yapılmış
olur. Tabii, VERI bir değişken olduğu için, programın başka bir kısmı içersinde
VERI değişkenine başka bir DOS dosyası atanabilir. Yeni dosya atamadan önce,
açık olan dosyayı kapatmak gerekir. Kapatma işlemi Close fonksiyonu ile
yapılır:
close(VERI);
deyimi, Sayilar.dat dosyasını kapatır. Bu
aşamadan sonra, VERI değişkenine başka bir dosya atanabilir. Örneğin,
Sayılar2.dat dosyasını atamak için
assign(VERI,
'Sayilar2.dat');
deyimi yeterli olacaktır.
Standart Pascal'da giriş/çıkış
işlemlerini yapan Input, Output text (yazı) dosyaları, program başlığında,
parantez içine yazılır:
Program
ad (Input, Output);
Bunun yanında, programın kullanacağı
başka dosyalar varsa, onlar da başlıkta parantez içine yazılmalıdır.
Program
ad (Input, Output, veri);
Turbo Pascal'da bu gerekli değildir ve
her hangi bir anlam taşımaz. Ama bazı Pascal sistemlerinde bu işlem dosyaları
çağrılabilmesi için gereklidir. Dosya bağlama bakımından Pascal sistemleri
arasında farklılıklar vardır. Burada anlatılacak yöntem Turbo Pascal'a özgüdür.
Input, Output standart kütükleri dışında,
Pascal'da bildirilen her kütük kullanmadan önce açılmalıdır. Pascal'da üç kütük
açma deyimi vardır, rewrite, append ve reset.
rewrite (Dosya_adı);
Standart Pascal prosedürüdür. Bu deyim
yeni bir kütük yaratmak istediğimiz zaman kullanılır ve boş bir kütük yaratır. Örneğin,
rewrite(VERI);
deyimi, yukardaki assign
deyiminden sonra verilmişse, sayilar.dat adlı boş bir kütük yaratılıyor. Şayet
sayilar.dat adlı bir kütük varsa bu kütük silinir ve yerine aynı adla yeni bir
boş kütük açılır. Dikkat ediniz! Her hangi bir nedenden dolayı kütüğün açılması
mümkün değilse (örneğin, disk doluysa), program, normal olarak bir yürütme hata
mesajı ile sona erer.
append (Dosya_adı);
Turbo Pascal prosedürüdür. Mevcut bir
kütüğün sonuna yeni veriler yazmak için kullanılır. Kütüğü silmeden açar ve
sonuna yeni verilerin yazılabilmesi için gerekli işlemler yapar. Bu mümkün
olmadığı zaman, program, bir yürütme hata mesajı ile sona erer.
Reset (Dosya_adı);
Standart Pascal
prosedürüdür. Mevcut bir dosyayı okunmak için açar. Örneğin,
reset(VERI);
deyimi, yukardaki assign
deyimden sonra verilmişse, sayılar.dat adlı kütüğü açar ve okunmak için
hazırlar. Öyle bir kütük yoksa program, bir hata mesajı ile sona erer.
Not 1
Rewrite ile Reset ve Append
ile Reset prosedürleri arasında Close kapatma prosedürü kulanılmalıdır. Aksi
taktirde kütüğün tümü yazılmayabilir.
Not 2
Kütük açma ile ilgili
işlemlerinde bir hatalı durum söz konusu ise, yukarda izah edildiği gibi,
normal olarak program bir yürütme hata mesajı ile sona erer. Bu sakıncalı ise,
Turbo Pascal'da programın sona ermesi
{$I -}
derleme komutu ile ortadan
kaldırılabilir. Ancak bu durumda, programda tespit edilen hataların
düzeltilmesi için bir imkan tanınmalı (örneğin, disket dolu ise, yeni bir
disketin takılması için zaman vermelidir) ve ancak durum düzeldikten sonra işlemler
devam etmelidir. Programda, giriş/çıkış işleminin hatalı olup olmadığını
öğrenmek için, Turbo Pascal'ın
IOResult
fonksiyonu çağrılabilir. Bu
fonksiyonun değeri 0 ise herşey iyi gidiyor, işlemler normal şekilde devam
edebilir. Değeri sıfırdan farklı ise, bir hata vardır. Hatanın ne olduğu,
IOResult fonksiyonun değerinden öğrenilebilir. Hata anlaşılınca, programda
gerekli önlem alınır. Giriş/çıkış hataları ortadan kaldırıldıktan sonra,
kaldığı yerden tekrar işleme devam edilmesi için
{$I +}
derleme komutu verilebilir.
Şimdi yazı kütüklerinin
yapısını ve kullanımını ele alalım. Daha önce ifade edildiği gibi bir yazı
kütügü satırlara ayrılmış bir char array‘idir. Satır sonunu (<eoln>
göstermek için ¿ simgesini ve dosya sonunu (EOF) göstermek için simgesini
kullanırsak,
A 45 66 78¿B
87 56 98¿C 55 76 78
karakter dizisi bir TEXT
(yazı dosyası) dır. Böyle bir kütük writeln/write fonksiyonları ile yazılabilir
ve readln/read fonksiyonları ile okunabilir.
Write ve writeln
fonksiyonları sayısal verileri bir karakter dizisine çevirerek dosyaya yazar.
Örneğin 45 sayısı kütükte '4' ve '5' karakterleri biçiminde saklanır. Benzer
şekilde read ve readln fonksiyonları, sayısal değişkenler kullanılarak
çağırılırsa, yukarıdaki işlemin tersini yaparlar. '4' ve '5' karakterleri
okunur ve 45 sayısına dönüştürülür.
Read/Readln ve Write/Writeln fonksiyonları genel yazı kütükleri için aynen
klavye girişinde olduğu gibi çalışır.
5.1. ÖRNEK.
program sonuclar(kutuk);
var
kutuk: text;
d: char;
s1, s2, s3: integer;
begin
assign(kutuk,
'sonuclar'); {Bağlama
işlemi}
rewrite(kutuk); {Açma
işlemi - yazmak için}
writeln(kutuk, 'A',
45:3, 66:3, 78:3); {Yazma işlemler - kütük}
writeln(kutuk,
'B', 87:3, 56:3, 98:3);
write(kutuk, 'C', 55:3,
76:3, 78:3);
close(kutuk); {Kapatma
işlemi}
reset(kutuk); {Açma
işlemi - okumak için}
readln(kutuk, d, s1, s2,
s3); {Okuma
işlemler - kütük}
writeln(d, s1:3, s2:3,
s3:3); {Yazma
işlemler - ekran}
readln(kutuk, d, s1, s2,
s3);
writeln(d, s1:3, s2:3,
s3:3);
read(kutuk, d, s1, s2,
s3);
write(d, s1:3, s2:3,
s3:3);
close(kutuk)
end.
Yukardaki örnekte kütüğün okunması
kolaydır; çünkü her satırda ne tür ve sayıda veri bulunduğunu biliyoruz. Ama
her zaman böyle olmayabilir. Çeşitli durumlar söz konusudur:
a)
Satırlarda ne bulunduğu biliyoruz, ama kaç satır olduğunu
bilmiyoruz.
b)
Satırlarda ne tür değerler bulunduğu biliyoruz, ama kaç tane
olduğunu bilmiyoruz.
c)
Değerler hakkında hiç bir şey bilmiyoruz.
(a) ve (b) durumlarında, eğer kütük sonu
ve/veya satır sonları bir şekilde bulunabilirse, problem döngüler ile
çözümlenebilir. (c) durumu umutsuz gibi görünüyor, ama satırlara ayrılmış bir
char dizisi olduğundan, her TEXT dosyası okunabilir. Gerçekten bu iş için Turbo
Pascal Editörü ve derleyici dahil, bir çok program tarafından yapılmaktadır.
Bir satırın sonuna gelinip
gelinmediği
eoln(<kütük değişkeni>);
fonksiyonu ile, bir
dosyanın sonuna gelinip gelinmediği ise
eof(<kütük değişkeni>);
fonksiyonları çağrılarak
öğrenilebilir. Bu iki fonksiyon boolean değerli olup normal olarak FALSE
değerine sahiptir. Ancak bir satır sonuna gelinirse eoln (End Of LiNe)
fonksiyonu TRUE değerini alır ve kütük sonuna gelinirse eof (End Of File)
fonksiyonu TRUE değerini alır. Genellikle bu fonksiyonlar bir while ... do ...
döngüsünde boolean ifade olarak kullanılırlar:
while not eof(....) do {Tüm kütük için}
begin
......
end;
while not eoln(...) do {Satırlar için}
begin
.....
end;
Şimdi bir örnek görelim:
Örnek: Aşağidaki program iki temel seçenek sunar.
(i) Bir kütüğe değişik sayıda
sayılardan oluşan bir satır eklemek.
(ii) Kütükteki her satıra ait sayıların ortalamasını hesaplayıp,
göstermek.
Örnek
program
SatirOrtalamasi(input, output, kutuk);
uses
crt;
procedure
SatirEkle;
var
kutuk: text;
sayi: real;
begin
clrscr;
assign(kutuk, 'satirlar');
{$I-}
append(kutuk); {Varsa, açılır}
if IOResult <> 0 then
rewrite(kutuk); {Değilse, yeni boş bir kütük açılsın}
{$I+}
write('Sayılar : ');
while not eoln(input) do {Klavye girişi için satır sonu (Enter)
kontrolü}
begin
read(sayi);
write(kutuk, sayi:8:2)
end;
readln; {Input'te satır sonu geçmek için}
writeln(kutuk); {Kütükte yeni bir satıra geç}
close(kutuk)
end;
procedure
Ortalamalar;
var
kutuk: text;
adet: byte;
sayi, top: real;
begin
clrscr;
assign(kutuk, 'satirlar');
{$I-}
reset(kutuk); {Okunacak}
if IOResult <> 0 then
begin
writeln('Kütük
bulunmadı. Bir tuşa basınız ve Menüden "Ekle" seçiniz');
while
not KeyPressed do;
exit
end;
{$I+}
writeln('Girilen
değerler ve ortalamalar:');
writeln;
while not eof(kutuk) do {Kütük için}
begin
adet := 0;
top := 0;
while not eoln(kutuk) do {Her satır için}
begin
adet := adet + 1; {Bir sayı daha}
read(kutuk, sayi); {Kütükten sayı al}
write(sayi:8:2); {Ekrana yaz}
top := top + sayi {Yeni toplam}
end;
readln(kutuk); {Kütükte yeni bir satıra geç}
if adet <> 0 then
writeln(' Ortalama: ', top/adet:6:2)
{Ekrana satır ortalamasını yaz ve yeni bir
satıra geç}
end;
writeln;
writeln('Devam etmek için bir tuşa
basınız');
while not KeyPressed do;
close(kutuk)
end;
procedure
bitti;
begin
clrscr;
halt
end;
function
menu:byte;
var
cevap: char;
begin
clrscr;
writeln('ANA MENÜ':44);
writeln;
writeln;
writeln('1':34,
' Satır ekle');
writeln('2':34,
' Ortalama');
writeln('3':34,
' Biti');
writeln;
writeln;
write('Seçiminiz
: ');
cevap := ReadKey; {Karakter giriş (Turbo Pascal) Enter tuşu gerekmez}
case cevap of
'1','s','S': menu := 1;
'2','o','O': menu := 2;
'3','b','B': menu := 3
end
end;
begin
repeat
case menu of
1: SatirEkle;
2:
Ortalamalar;
3:
Bitti {Çıkış}
end
until FALSE {Koşulsuz devam}
end.
Notlar
1. SatirEkle yordamında önce bir append
çağrısı yapılıyor. Kütük bulunuyorsa açılır ve sonuna değerler yazmak için
hazırlanır. Mevcut değilse bir Giriş/Çıkış hatası meydana gelir. Append'den
önce {$I-} derleyici komutu verildiği için program durmaz ama IOResult
fonksiyonu sıfır olmayan bir değer alır. Bu durumda
if IOResult
<> 0 then
rewrite(kutuk);
deyimindeki
rewrite(kutuk)
çağrısı işler ve yeni boş
bir kütük açılır. Böylece, her iki durumda, kütüğe bir satır dolusu sayı yazabiliriz.
Sayıların klavyeden okunması ve kütüğün kayıt edilmesi
while not
eoln(input) do
begin
read(sayi);
write(kutuk, sayi:8:2)
end;
döngüsü ile yapılır. Yazarken sayılar
arasında (en az) bir boşluk bulunmalı, ama satır sonunda bir boşluk bulunmamalıdır.
Nedeni biraz sonra anlaşılacaktır. Bu sonuç sayıların belli bir alanın sağında
yazılması ile elde edebilir. Örnekte sayi:8:2
kullanılır, yani 8 karakterlik bir alan kullanılır.
2. Yukardaki döngüden anlaşılacağı gibi
eoln fonksiyonu klavye giriş (yani, input yazı kütüğü için) kullanılabillir.
Giriş yapılırken değerle aynı satır üzerine yazılır ve giriş Enter tuşuyla
tamamlanır. Benzer şekilde eof fonksiyonunda da kullanılabilir. Girişi sona
erdirmek için normal olarak Ctrl-Z ile Enter tuşlar kullanılır, ama crt birimi
kullanılırsa sadece Ctrl-Z yeterlidır. Ancak bu durumda, programın iş gören
kısımının başında
CheckEOF := TRUE
deyimini kullanmak
gereklidir çünkü normal olarak crt biriminde tanımlanan bu değişkenin değeri
FALSE olur ve Ctrl-Z için bir kontrol yapılmıyor.
3. Ortalamalar yordamında kütük reset deyim ile
açılmaya çalışılıyor. Bu mümkün olmuyorsa IOResult fonksiyonun değeri sıfırdan
farklı olur, bir mesaj yazılır ve Exit fonksiyon ile ana menüye dönülür.
Satırlar aşağıdaki döngü ile okunur. Okunma read(kutuk, sayi) ile yapılıyor
çünkü readln(kutuk, sayi) sadece satırdaki ilk değerini okuyup, yeni bir satıra
geçecektir. Satırdaki tüm sayılar okunduktan sonra eoln(kutuk) FALSE olur ve
döngü sona erer. Bu son satır değilse readln(kutuk) komut sayısında satır sonu
geçirilir, dıştaki while not eof(kutuk) do..... döngü sayısında yeni bir satır
okunur.
while not eoln(kutuk)
do {Her satır için}
begin
adet := adet + 1; {Bir sayı daha}
read(kutuk, sayi); {Kütükten sayı al}
write(sayi:8:2); {Ekrana yaz}
top := top + sayi {Yeni toplam}
end;
readln(kutuk); {Kütükte yeni bir satıra geç}
Burada, niçin satır sonunda bir boşluk
olmaması gerektiğini açıklayalım. Aşağıdaki satırları düşünelim. Sonunda bir
boşluk vardır.
45 8 76 ¿
67 88 ¿
76 okunduktan sonra okunma noktası boşluk
damgasına gelir. Eoln fonksiyonun değeri halen FALSE' tur, çünkü bu satırda
okunacak bir damga vardır. O halde, döngü sona ermez ve read fonksiyonu tekrar
çağrılır. Sayısal değerler okunurken bu fonksiyon boşlukları, yeni satırlar ve
tablar ("Ak Boşluk") dan geçip, mütakip bir sayı okur. Böylece ikinci
satırdaki 67 sayısı okunur; yani okunma satır sonunda durmaz. Tabii ki boşluk
yoksa, ilk satırdaki 76 sayısı okunduktan sonra okunma noktası satır sonuna
gelir, eoln fonksiyonun değeri TRUE olur ve döngü sona erer.
Sonucu görebilmemiz için,
program akışı
KeyPressed
fonksiyonu ile
durdurulabilir. Bu özel Turbo Pascal boolean değerli fonksiyonu normal olarak
FALSE değere sahiptir, ancak bir tuşa basıldığı zaman TRUE olur. O halde
while not
KeyPressed do;
döngüsü, ancak bir tuşa basıldığı zaman
sona erer.
4. Menu fonksiyonun değeri, yapılan seçime
göre, 1, 2 veya 3 tür. Seçim elde etmek için Turbo Pascal'ın özel
ReadKey
fonksiyonu ile elde edilir. Normal bir
tuş basıldığı zaman ReadKey'in değeri o tuşun ASCII kodudur (sade tuş
basılacak, giriş Enter tuşu ile tamamlamaz). Özel tuşlar (Örneğin F1..F12
fonksiyon tuşları) için ReadKey'in değeri 0 olur. Bu durumda ReadKey tekrar
çağrılırsa o tuşa ait özel bir kod elde edilir.
5. Programın ana kısımında menu fonksiyonu
"sonsuz" bir döngü içersinde çağrılır. Fonksiyonun her değeri için
ilgili yordam çağrılır. Tek çıkış yolu Bitti yordamı olur, çünkü bu yordam Halt
(Dur) fonksiyonunu çağırır.
Şimdi
bir yazı dosyasının damga - damga okunmasına gelelim. c char tipinden bir
değişken olsun. Dosyanın okunması için aşağıdaki gibi iç-içe döngüler
kullanılabilir:
while not
eof(kutuk) do
begin
while not eoln(kutuk) do
begin
read(kutuk, c);
{satır içi işlemler}
end;
readln(kutuk);
{satır arasında işlemler}
end;
Standart Pascal'da satır sonu işaretler
bir boşluk (ASCII 32) olarak görünür. Turbo Pascal'da ise satır sonu işareti
DOS tarafından kullanılan ASCII 13 ve ASCII 10 damgalar çifti olarak görünür. O
halde amacımız sadece kütüğün ekran üzerinde gösterilmesi ise
while not
eof(kutuk) do
begin
read(kutuk, c);
write(c)
end;
yeterli olur. Bu döngü Standart Pascal'da
istenilen sonucu vermez; çünkü satır sonları bir boşluk olarak gösterilecek,
yani ekran üzerinde yeni bir satıra geçilemeyecektir. Standart Pascal'da
while not
eof(kutuk) do
begin
while not eoln(kutuk) do
begin
read(kutuk, c);
write(c)
end;
readln(kutuk);
writeln
end;
döngüleri gereklidir.
Örnek
Aşağıdaki ilk program basit bir dosya
yaratır; ikinci program bunu okur ve ekran üzerine sırayla yazar. Kullanılacak
DOS kütük adı DOS Komut Dizgisinden alınır. Bir
program DOS komut dizgisinden işleme konulduğu zaman, addan sonra parameterler
verilebilir. Turbo
Pascal'da verilen parameter sayısı
ParamCount
özel fonksiyonunun değeri olarak programa
ulaşır, ve parameterler (string olarak)
ParamStr(1),
... ParamStr(ParamCount)
şeklinde kullanılabilir. Programın adı
KutukYaz olduğuna göre, KutukYaz.pas olarak saklanıp diske derlenirse
KutukYaz.exe adlı bir makine programı elde edilir. DOS
komut dizgisinde (örneğin)
A:>KutukYaz ornek
şeklinde işleme konulursa
ParamCount = 1 ve ParamStr(1) = 'ornek' olacaktır. O halde programdaki
assign(k,
ParamStr(1))
deyimi, aslında k kütük değişkeni 'ornek'
adlı DOS kütüğüne bağlayacaktır.
Not
Parameterler isteyen bir programı Turbo
Pascal Ortamından çalıştırmak
için gerekli parameterler
Ana Menüdeki
Options/Parameters
seçeneği yardımı ile
verilebilir.
Örnek
program KutukYaz(output,
k);
var
k: text;
begin
if ParamCount <> 1 then
{bir tane parameter bekleniyor}
writeln('Kullanımı: KutukYaz <DOS kütük Adı>')
else
begin
assign(k, ParamStr(1));
rewrite(k);
writeln(k, 'Pascal'); {örnek
değerler}
writeln(k, 'Cobol');
write(k, 'Fortran');
close(k);
writeln('Kütük yazıldı')
end
end.
Yazılan kütük Turbo Pascal Editörü, DOS
type komutu ya da aşağıdaki program ile okunabilir:
program KutukOk(output, k);
var
k: text;
c: char;
begin
if ParamCount <> 1 then
writeln('Kullanımı: KutukOk <DOS kütük adı>')
else
begin
assign(k, ParamStr(1));
reset(k);
while not eof(k) do {Turbo Pascal için kısa yazılma yolu}
begin
read(k, c);
write(c)
end;
close(k);
writeln;
writeln('Kütük Sonu')
end
end.
Tabii ki bu program sadece
birinci program tarafından yazılan kütüğü değil, her hangi bir yazı kütüğünü
okutmak için kullanılabilir.
Örnek
Bu program DOS komut dizgisinde ilk parametre olarak verilen kütüğü açar,
küçük harfleri büyük harf olarak yazarak ikinci parametre olarak verilen kütüğü
oluşturur. Ayrıca kütükteki satırlar sayılır ve sonuç ekrana gönderilir.
program
ust_hal(output);
uses
crt;
var
giris_kutuk, cikis_kutuk : text;
cevap : char;
sayac : integer;
procedure
kutuk_cevir(var s : integer);
var
c : char;
giris, cikis: text;
begin
assign(giris, ParamStr(1)); {birinci parameter}
assign(cikis, ParamStr(2)); {ikinci parameter}
{$I-}
reset(giris);
if IOResult <> 0 then
begin
writeln('Giriş kütük bulunmadı');
halt
end;
rewrite(cikis);
if IOResult <> 0 then
begin
writeln('Çıkış kütük açılmadı');
halt
end;
{$I+}
s := 0; {satir sayac icin baslangic degeri}
while not eof(giris) do
begin
while not eoln(giris) do
begin
read(giris, c); {giriş kütükten karakter okur}
write(cikis, upcase(c)) {ve çıkış
kütüğüne büyük harf olarak yaz}
end;
readln(giris);
writeln(cikis);
s := s + 1 {bir satır daha}
end;
close(giris);
close(cikis)
end;
procedure
kutuk_goster;
var
c : char;
yeni: text;
begin
assign(yeni, ParamStr(2)); {yeni kütük}
reset(yeni);
while not eof(yeni) do
begin
while not eoln(yeni) do
begin
read(yeni,c);
write(c)
end;
readln(yeni);
writeln
end;
close(yeni)
end;
begin
if ParamCount <> 2 then {iki parameter olmali}
writeln('Kullanimi :
ust_hal <giris_kutuk> <Cikis_kutuk>')
else
begin
clrscr;
writeln('Lütfen
bekleyiniz ... ');
writeln;
kutuk_cevir(sayac);
writeln(sayac,' satir okundu ve büyük
harfe çevirildi.');
writeln;
write('Yeni kütük görmek istiyor
musunuz? (E/H) : ');
repeat
read(cevap);
cevap
:= upcase(cevap)
until cevap
in ['E','H'];
if cevap = 'E' then
begin
kutuk_goster;
writeln;
writeln('Kutuk sonu.')
end
end
end.
Reset(In_File) In_File adlı dosyayı okunmak üzere hazırlar; yani dosyayı okunmak üzere açar, dosya işaretcisi dosyanın ilk bileşenini işaret eder. Eğer dosya boşsa ya da bu adla bir dosya yoksa, EOF(In_File) fonksiyonu TRUE değerini, değilse FALSE değerini alır.
Rewrite(Out_File) Out_File adlı dosyayı yazmak için hazırlar. Dosyayı açar ve dosya işaretçisi dosyanın ilk bileşenini gösterir. Bu adla bir dosya yoksa, açarken onu yaratır. Bu adla bir dosya varsa, onun içeriğini tamamen siler ve yeni bir dosya açıyormuş gibi, ilk bileşenini göstermeye başlar. Bu işlemle silinen dosyanın içeriği bir daha bulunamaz. Dolayısıyla, var olan dosyaları yanlışlıkla silmemek için, Rewrite deyiminin önüne bir denetim procedürü konulmalıdır.
EOF(In_File) EOF, İngilizce’deki “End Of File” deyiminin kısaltılmışıdır. Açık dosyanın son bileşenine gelinip gelinmediğini söyler. Dosya işaretçisi, In_File dosyasının son bileşenine gelince EOF(In_File) fonksiyonu TRUE değerini, aksi halde FALSE değerini alır.
EOLN(In_File) Dosya işaretçisinin bulunduğu satırda başka karakter olup olmadığını söyler. İşaretçi satırın son bileşenine geldiğinde EOLN(In_File) TRUE değerini, aksi halde FALSE değerini alır.
Read(In_File, ch) Dosya işaretçisinin gösterdiği bileşeni okur ve ch değişkenine aktarır. Böylece, sözkonusu bileşen, ch değişkeni yardımıyla ana belleğe taşınır ve onunla istenilen işlemler yapılabilir.
Readln(In_File) Read(In_File) deyiminin yaptığı işi aynen yapar; ancak karakteri okuduktan sonra dosya işaretçisi bulunduğu satırdan bir sonraki satıra geçer.
Write(Out_File,ch) Read deyiminin tersini yapar. Ch değişkeninin değerini Out_file dosyasında, işaretçinin bulunduğu yere yazar.
Writeln(Out_File,ch) Write deyiminin yaptığı işi aynen yapar; ancak ch değerini dosyaya yazdıktan sonra <eoln> karakterini ekler. Dolayısyla, yazdığı karakter satırın sonu olur. Ondan sonrakiler bir sonraki satıra yazılır.
Assign(IO_File, ‘Deneme.txt’) ‘Deneme.txt’ adlı dosyayı, IO_File adlı dosya değişkenine bağlar. Başka bir deyişle, IO_File değişkeninin kayıt ortamındaki eşidir (değeridir). IO_File ile yapılacak bütün işler ‘Deneme.txt’ üzerinde gerçekleşir.
Close(IO_File) IO_File dosyasını kapatır.
Append(IO_File) IO_Dosyasını sonuna ek yapılmak üzere hazırlar. Rewrite deyiminin yaptığı işi yapar; ancak IO_File dosyasını silmez, işaretçi, son bileşeninden sonraki ilk boş bileşen üzerinde durur. Dolayısıyla, yeni kayıtlar dosyanın sonuna eklenir.
Erase(IO_File) IO_file dosyasını kayıt ortamından (disket, disk) silen prosedür. Silme işleminin olabilmesi için IO_File dosyası kapalı olmalıdır.
Rename(IO_File, Yeni_Ad) Dosyanın kayıt ortamında kendisine eşlenen adını değiştirir.
SeekEOF(IO_File) IO_File dosyasında boşluk, tab, eoln karakterlerinden başka bir karakter olup olmadığını bildirir. Bu fonksiyon EOF fonksiyonuna benzer; ancak boşluk, tab, eoln karakterlerini atlar. EOF ‘a ulaşmadan önce başka karaktere raslarsa FALSE, değilse TRUE değerini verir.
SeekEOLN(In_File) In_File dosyasında, dosya işaretçisinin bulunduğu satırda boşluk ve tab’ dan başka karakter olup olmadığını bildirir. EOLN fonksiyonuna benzer; ancak boşluk ve tab karakterlerini atlar. EOF ‘a ulaşmadan önce başka karaktere raslarsa FALSE, değilse TRUE değerini verir.
Flush(Out_File) OUT_File dosyasına yazılmak istenen verilerin gerçekten dosyanın bulunduğu fiziksel ortama yazılmasını garanti eder. Turbo Pascal, text dosyası yaratırken, bazen, dosyaya gönderilen verileri bellekte tutmaya devam eder. Flush prosedürü, bellekte bekleyen verilerin kayıt ortamına gitmesini sağlar.