6.Ders : C Dosya İşleme

Bu derste, C’deki (file handling) dosya işleme ve kullanımı hakkında bilgi edineceksiniz. Fprintf(), fscanf(), fread(), fwrite(), fseek() vb. kullanarak standart C’yi kullanmayı örnekleri ile öğreneceksiniz.

Neden dosyalar gerekli?
Bir program sonlandırıldığında tüm veriler kaybolur. Bir dosyada saklamak, program sonlandırılsa bile verilerinizi koruyacaktır.

Çok sayıda veri girmeniz gerekiyorsa, hepsini girmeniz çok zaman alacaktır.

Ancak, tüm verileri içeren bir dosyanız varsa, C’deki birkaç komutu kullanarak dosyanın içeriğine kolayca erişebilirsiniz.

Verilerinizi bir bilgisayardan diğerine herhangi bir değişiklik yapmadan kolayca taşıyabilirsiniz.

Dosya Türleri

Metin dosyalar
Binary dosyalar

  1. Metin dosyaları
    Metin dosyaları normal .txt dosyalarıdır. Not Defteri gibi herhangi bir basit metin düzenleyiciyi kullanarak kolayca metin dosyaları oluşturabilirsiniz.

Bu dosyaları açtığınızda, dosyadaki tüm içeriği düz metin olarak görürsünüz. İçeriği kolayca düzenleyebilir veya silebilirsiniz.

Bakım yapmak için az çaba harcarlar, kolayca okunurlar ve en az güvenlik sağlarlar ve daha büyük depolama alanı alırlar.

2. Binary dosyalar
Binary dosyalar çoğunlukla bilgisayarınızdaki .bin dosyalarıdır.

Verileri düz metin olarak saklamak yerine, ikili biçimde (0 ve 1’ler) depolarlar.

Daha yüksek miktarda veri tutabilirler, kolayca okunamazlar ve metin dosyalarından daha iyi güvenlik sağlarlar.

Dosya İşlemleri

C’de, dosyalar üzerinde dört ana işlem gerçekleştirebilirsiniz:

  • Yeni bir dosya oluşturma.
  • Mevcut bir dosyayı açmak.
  • Bir dosyayı kapatma.
  • Bir dosyadan bilgi okuma ve yazma.

Dosyalarla çalışmak

Dosyalarla çalışırken, bir tür dosya göstericisini bildirmeniz gerekir. Bu bildirim dosya ile program arasındaki iletişim için gereklidir.

FILE *fptr;

Bir dosyayı açma – oluşturma ve düzenleme için

Bir dosyayı açmak stdio.h başlık dosyasında tanımlanan fopen() fonksiyonu kullanılarak gerçekleştirilir.

Bir dosyayı standart G / Ç’de açmak için kullanılan sözdizimi şöyledir:

ptr = fopen("fileopen","mode");

Örneğin :

fopen("E:\\cprogram\\newprogram.txt","w");
fopen("E:\\cprogram\\oldprogram.bin","rb");

Yazma modu, dosyanın içeriğini oluşturmanıza ve düzenlemenize (üzerine yazmanıza) izin verir.

Okuma modu sadece dosyayı okumanıza izin verir, dosyaya yazamazsınız.

Standart Giriş / Çıkışlarda Açma Modları

ModModun AnlamıDosyanın durumu
rOkumak için açar.Dosya yoksa fopen (), NULL değerini döndürür.
rbİkili modda okumak için açar.Dosya yoksa fopen (), NULL değerini döndürür.
wYazmak için açarDosya varsa, içeriğinin üzerine yazılır.
Dosya yoksa, oluşturulur.
wb İkili modda yazmak için açar. Dosya varsa, içeriğinin üzerine yazılır.
Dosya yoksa, oluşturulur.
aEklemek için açar.
Veriler dosyanın sonuna eklenir.
Dosya yoksa oluşturulur.
abİkili modda eklemek için açar.
Veriler dosyanın sonuna eklenir.
Dosya yoksa oluşturulur.
r+Hem okuma hem de yazma için açar.Dosya yoksa fopen (), NULL değerini döndürür.
rb+Hem okuma hem de yazma için ikili modda açar. Dosya yoksa fopen (), NULL değerini döndürür.
w+Hem okuma hem de yazma için açar.Dosya varsa, içeriğinin üzerine yazılır.
Dosya yoksa, oluşturulur.
wb+Hem okuma hem de yazma için ikili modda açar. Dosya varsa, içeriğinin üzerine yazılır.
Dosya yoksa, oluşturulur.
a+Hem okumak hem de eklemek için açar.Dosya yoksa, oluşturulur.
ab+Hem okumak hem de eklemek için ikili modda açın.Dosya yoksa, oluşturulur.

Bir dosyayı kapatma
Dosya (hem metin hem de ikili) okuma / yazma işleminden sonra kapatılmalıdır.

Bir dosyayı kapatmak, fclose() işlevi kullanılarak gerçekleştirilir.

fclose(fptr);

Burada, fptr, kapatılacak dosyayla ilişkili bir dosya işaretçisidir.

Metin dosyasına okuma ve yazma
Bir metin dosyasına okumak ve yazmak için, fprintf () ve fscanf () işlevlerini kullanırız.

Bunlar sadece printf () ve scanf () dosya sürümleridir. Tek fark, fprint () ve fscanf () öğesinin FILE yapısında bir işaretçi beklemesidir.

Örnek 1: Bir metin dosyasına yazmak :

#include <stdio.h>
#include <stdlib.h>
int main()
{
   int num;
   FILE *fptr;
   fptr = fopen("C:\\program.txt","w");
   if(fptr == NULL)
   {
      printf("Hata!");   
      exit(1);             
   }
   printf("Enter num: ");
   scanf("%d",&num);
   fprintf(fptr,"%d",num);
   fclose(fptr);
   return 0;
}

Bu program kullanıcıdan bir numara alır ve program.txt dosyasında saklar.

Bu programı derleyip çalıştırdıktan sonra, bilgisayarınızın C sürücüsünde oluşturulan bir program.txt dosyasını görebilirsiniz. Dosyayı açtığınızda, girdiğiniz tamsayıyı görebilirsiniz.

Örnek 2: Bir metin dosyasından okumak :

#include <stdio.h>
#include <stdlib.h>
int main()
{
   int num;
   FILE *fptr;
   if ((fptr = fopen("C:\\program.txt","r")) == NULL){
       printf("Error! opening file");
       // Program exits if the file pointer returns NULL.
       exit(1);
   }
   fscanf(fptr,"%d", &num);
   printf("Value of n=%d", num);
   fclose(fptr); 
  
   return 0;
}

Bu program program.txt dosyasında bulunan tam sayıyı okur ve ekrana yazdırır.

Dosyayı Örnek 1’den başarıyla oluşturduysanız, bu programı çalıştırarak girdiğiniz tamsayıyı alır.

Fgetchar (), fputc () vs. gibi diğer fonksiyonlar da benzer şekilde kullanılabilir.

İkili bir dosyaya okuma ve yazma
Fread () ve fwrite (), ikili dosyalar biçiminde sırasıyla diskteki bir dosyadan okumak ve yazmak için kullanılır.

İkili dosyaya yazma
İkili bir dosyaya yazmak için fwrite () işlevini kullanmanız gerekir. İşlevler dört argüman alır:

1-diske yazılacak verinin adresi
2-diske yazılacak verilerin boyutu
3-veri sayısı
4-yazmak istediğiniz dosyadaki işaretci

fwrite(addressData, sizeData, numbersData, pointerToFile);

Örnek 3: fwrite () kullanarak ikili bir dosyaya yazmak :

#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
   int n1, n2, n3;
};
int main()
{
   int n;
   struct threeNum num;
   FILE *fptr;
   if ((fptr = fopen("C:\\program.bin","wb")) == NULL){
       printf("Error! opening file");
       // Program exits if the file pointer returns NULL.
       exit(1);
   }
   for(n = 1; n < 5; ++n)
   {
      num.n1 = n;
      num.n2 = 5*n;
      num.n3 = 5*n + 1;
      fwrite(&num, sizeof(struct threeNum), 1, fptr); 
   }
   fclose(fptr); 
  
   return 0;
}

Bu programda, C sürücüsünde program.bin adlı yeni bir dosya oluşturuyoruz.

n1, n2 ve n3 olmak üzere üç sayı içeren bir threeNum yapısını ilan ediyoruz ve bunu ana fonksiyonda num olarak tanımlıyoruz.

Şimdi, for döngüsü içinde, değeri fwrite () kullanarak dosyaya kaydederiz.

İlk parametre num adresini alır ve ikinci parametre üç sayı yapısının boyutunu alır.

Yalnızca bir num örneği eklediğimiz için, üçüncü parametre 1’dir. Ve, son parametre * fptr verileri sakladığımız dosyayı gösterir.

ve dosyayı kapattık.

İkili dosyadan okuma

Fread () işlevi, yukarıdaki fwrite () işlevine benzer 4 argüman alır.

fread(addressData, sizeData, numbersData, pointerToFile);

Örnek 4: fread () kullanarak ikili dosyadan okuma

#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
   int n1, n2, n3;
};
int main()
{
   int n;
   struct threeNum num;
   FILE *fptr;
   if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
       printf("Error! opening file");
       // Program exits if the file pointer returns NULL.
       exit(1);
   }
   for(n = 1; n < 5; ++n)
   {
      fread(&num, sizeof(struct threeNum), 1, fptr); 
      printf("n1: %d\tn2: %d\tn3: %d", num.n1, num.n2, num.n3);
   }
   fclose(fptr); 
  
   return 0;
}

Bu programda, program.bin dosyasını okursunuz ve kayıtları birer birer döngüden geçirirsiniz.

Basit bir ifadeyle, * fptr ile gösterilen dosyadan üç sayı büyüklüğünde bir üç sayı kaydedersiniz. Örnek 3’e eklediğiniz kayıtları alırsınız.

fseek () kullanarak veri alma

Bir dosyanın içinde çok sayıda kayda sahipseniz ve belirli bir pozisyondaki bir kayda erişmeniz gerekiyorsa, kaydı almak için önce tüm kayıtlardan geçmeniz gerekir.

Bu, çok fazla bellek ve çalışma zamanını boşa harcar. Gerekli verileri elde etmenin daha kolay bir yolu fseek () kullanılarak elde edilebilir.

Adından da anlaşılacağı gibi, fseek () imleci dosyadaki belirtilen kayda göre arar.

fseek(FILE * stream, long int offset, int whence);

İlk parametre dosyanın işaretçisidir. İkinci parametre, bulunacak kaydın konumudur ve üçüncü parametre, ofsetin başladığı konumu belirtir.

Örnek 5: fseek ()

#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
   int n1, n2, n3;
};
int main()
{
   int n;
   struct threeNum num;
   FILE *fptr;
   if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
       printf("Error! opening file");
       // Program exits if the file pointer returns NULL.
       exit(1);
   }
   
   // Moves the cursor to the end of the file
   fseek(fptr, -sizeof(struct threeNum), SEEK_END);
   for(n = 1; n < 5; ++n)
   {
      fread(&num, sizeof(struct threeNum), 1, fptr); 
      printf("n1: %d\tn2: %d\tn3: %d\n", num.n1, num.n2, num.n3);
      fseek(fptr, -2*sizeof(struct threeNum), SEEK_CUR);
   }
   fclose(fptr); 
  
   return 0;
}

Bu program, program.bin dosyasındaki kayıtları ters sırayla (en sondan önceye) okumaya başlayacak ve yazdıracaktır.