Temel C Programlama -51- Dosya İşaretçisi ve feof() Fonksiyonu

Daha öncesinde bir dosya oluşturmayı ve bu dosyaya veri yazmayı anlattık. Fakat dosya işlemleri sadece bunlarla sınırlı değildir. stdio.h başlık dosyasına baktığımızda daha farklı dosya okuma ve yazma fonksiyonlarının olduğunu görmekteyiz. Fakat daha öncesinde dosya işaretçisi ve feof() fonksiyonlarından bahsetmek istiyoruz.

Dosya Okuma ve Yazma Fonksiyonları

Daha öncesinde bir dosya işaretçisinin olduğunu ve dosyaya aynı bir karakter dizisi gibi bakıldığını söylemiştik. Dosya işaretçisi dosyanın başından EOF işaretine yani dosya bitimine kadar ileri ve geri olarak çizgisel olarak ilerlemekte ve bu işaret ettiği bölgeler üzerine okuma ve yazma yapmaktadır. Bunu bir teyp bandı ve teyp kafası gibi düşünebilirsiniz. Teyp bandının başlangıcı ve sonu olmakta ve teyp kafası sadece bir noktayı okumaktadır. Teyp sağa veya sola ilerleyerek okuma konumunu değiştirmektedir. Aşağıdaki resim tam da bizim dediğimizi göstermektedir.

Resim https://www.ntu.edu.sg/home/ehchua/programming/java/images/IO_RandomAccessFile.png

Burada dosya işaretçisi her yazma ve okuma yaptığı zaman işaretçiyi sağa kaydırmakta ve dosyanın en son kısmına geçmektedir. Bunu aynı yazı yazdığınız zaman yanıp sönen imlece benzetebilirsiniz. Klavyeden her harfi girdiğinin zaman imleç birer birer sağa kaymakta ve yazdığınız harfleri boş kısma eklemektedir. Siz dilediğiniz zaman imleci başa veya metinde herhangi bir yere alabilirsiniz. Bu imleçle (işaretçi) ile alakalı fonksiyonları daha sonra anlatacağız. Şimdilik konuyu basit seviyede tutmak için sadece okuma ve yazma üzerinden gideceğiz ve imleci kendi halinde bırakacağız.

Burada EOF (End of File) işaretini de dikkat çekmek isterim. EOF işareti karakter dizilerinde kullanılan ‘\0’ gibi veya klavyedeki Return, Backspace tuşları gibi bir ASCII karakteri değildir. Aslına baktığınızda EOF işaretinin C standartında bile olmadığını görürsünüz. Bu işaret sistem tarafından belirlenir ve EOF diyerek kullanılır. Bunun değeri sisteme göre de değişmektedir. EOF dosyanın bittiği haberini bize vermektedir. EOF işareti bir ASCII karakteri olmasa da bunu EOF olarak bayt şeklinde okuyup değerlendirebiliriz. Yalnız her zaman EOF diye belirtmemiz gereklidir. Çünkü EOF’un ne değerde olacağı kesin değildir. Peki EOF’u dosya içerisinde nasıl bulacağız?, diye soracağınızı biliyorum. O halde feof() fonksiyonunu anlatarak konumuza devam edelim.

feof() fonksiyonu

Bu fonksiyon dosya işaretçisinin işaret ettiği dosya bölümünde EOF işaretinin olup olmadığını denetler. Eğer EOF işareti varsa sıfırdan farklı bir değer döndürür. Eğer EOF işareti yoksa sıfır değerini döndürür. Genellikle dosya okuma ve yazma işlemlerinde if karar yapısı veya while döngüsü ile beraber kullanılır. EOF işaretine rastlanıldığında dosya kapatılır veya oradan itibaren yazıma devam edilir.

Şimdi feof() fonksiyonunun prototipine bakalım.

int feof ( FILE * stream );

Bu fonksiyon yukarıda bahsettiğimiz gibi int tipinde değer döndürmekte. Dönen değer sıfırdan farklı ise EOF tespit edilmiştir eğer sıfır ise EOF tespit edilmemiştir. Aldığı argüman FILE * stream olduğu için dosya işaretçisi tipinde yani açıp üzerinde çalıştığımız FILE tipindeki işaretçiyi buna argüman olarak aktarmamız gereklidir. Unutmayın, feof() fonksiyonu dosyada EOF olup olmadığını değil dosya işaretçisinin işaret ettiği yerde EOF olup olmadığını bize bildirir. Şimdi bununla ilgili bir örneğe göz atalım. Bu örneği cplusplus.com sitesinden aldığımı belirteyim.

#include <stdio.h>

int main ()
{
  FILE * pFile;
  int n = 0;
  pFile = fopen ("dosya.txt","rb");
  if (pFile==NULL) perror ("Dosya Bulunmadi");
  else
  {
    while (fgetc(pFile) != EOF) {
      ++n;
    }
    if (feof(pFile)) {
      puts ("End of File Okundu.");
      printf ("Toplam okunan bayt: %d\n", n);
    }
    else puts ("End of File Okunamadi.");
    fclose (pFile);
  }
  system("PAUSE");
  return 0;
}

Bu program ele alınan dosyanın mevcut olup olmadığına ve mevcutsa bulundurduğu içeriğe göre farklı çıkışlar verecektir. Fakat öncesinde sizin bu programı iyice sindirmeniz için satır satır açıklayacağım. Siz programa bakıp hangi komutun ne amaçla kullanıldığını söyleyebilmeniz gereklidir.

FILE * pFile; Burada üzerinde açıp işlem yapacağımız dosya için bir dosya işaretçisi değişkeni oluşturuyoruz. FILE tipindeki değişkenler özel değişkendir ve dosya üzerinde işlem yapmak için tanımlanması zaruridir.

int n = 0; Programın devamında kullanılmak üzere bir sayaç değişkenini burada tanımladık. n değişkeni burada n adet bayt olarak tanımlanmıştır. Devamında ne maksatla kullanıldığını daha iyi göreceksiniz.

pFile = fopen (“dosya.txt”,”rb”); Burada uygulamanın klasöründe yer alan dosya.txt adlı dosyayı açıyor ve binary olarak okuyoruz. Bunu “rb” argümanıyla belirttik. Eğer dosya.txt diye bir dosya mevcut değilse bu fonksiyon NULL değerini yani boş değeri döndürmekte. Sonrasında ise geri dönen değeri pFile adlı dosya işaretçisine aktarıyoruz.

if (pFile==NULL) perror (“Dosya Bulunmadi”); Burada eğer pFile, NULL değerine eşitse perror fonksiyonu ile bir hata mesajı yazdırıyoruz. Burada perror() fonksiyonunu ilk defa gördüğümüzden bu fonksiyonu sizlere açıklayalım. Daha öncesinde akışları anlatırken stdin, stdout ve stderr adlı akışlar olduğundan bahsetmiştik. stdin ve stdout akışlarını şimdiye kadar birden fazla kez anlattık. stderr akışının da hata mesajlarının yazıldığı bir akış olduğundan bahsetmiştik. İşte burada da hata akışına bir mesaj yazdırmak için perror() fonksiyonunu kullanmaktayız. perror() fonksiyonu içine yazacağımız karakter dizisi hata mesajı olarak yorumlanacak ve yazdırılacaktır. Bu üretilen hata mesajı platforma göre değişiklik göstermektedir.

while (fgetc(pFile) != EOF) { ++n; } Yukarıda dosya işaretçisinin NULL olup olmadığını denetledik ve NULL ise hata mesajı yazdırmasını söyledik. Eğer değilse yani dosya varsa bu sefer de fgetc() fonksiyonu ile dosyayı karakter karakter okumaktayız. Normalde getc() fonksiyonu klavyeden bir karakter okumak için kullanılmaktaydı. Aynı şekilde fgetc() fonksiyonu bunun dosya fonksiyonu sürümü olarak karşımıza çıkmaktadır. EOF okunana kadar n değeri birer birer artırılmaktadır. Bu da dosyanın başından sonuna kadar kaç karakter okunduğunu n değişkeninde bize vermektedir.

if (feof(pFile)) Bu komut eğer EOF okunursa çalıştırılacak bir karar yapısıdır. Yukarıda zaten while döngüsü ile EOF kullanılmış ve aslında bunu kullanmaya pek gerek kalmamıştır. Eğer EOF okunursa toplam okunan baytı yazdırmak için stdout akışına n değişkeni yazdırılır. Eğer EOF okunmazsa EOF’un okunmadığı hatası verilir. Eğer EOF okunmadıysa yukarıdaki döngüden çıkma ihtimali de yoktur. Daha önce dediğim gibi zamanım olmadığından hazır örnek kullanayım dedim. 🙂

Ben daha önceki örnekte yer alan “Merhaba Dunya” yazılı dosya.txt dosyasını okuttum ve şöyle bir sonuç verdi. Siz değişik dosyalarla veya dosyasız da deneyip sonuçları gözlemleyebilirsiniz.

Bu yazıda feof(), perror() ve fputc() fonksiyonlarını öğrendik. Diğer dosya fonksiyonlarını öğrenmeye devam edeceğiz.

Last updated