Borsa Youtube kanalımız ve Twitter hesabımız 08 Haziran 2023 tarihinden itibaren yayında...
Dosya giriş/çıkış işlemlerini gerçekleştirmek için programlarımızın başına <fstream> başlık dosyasını eklememiz gerekir. Bu dosyada ifstream, ofstream ve fstream sınıflarının da yer aldığı bazı sınıf bildirimleri yer alır. Bu sınıflar sırasıyla, ios sınıfından türetilen istream, ostream ve iostream sınıflarından türetilmiş olduğundan, ios sınıfı içindeki tüm değişken ve fonksiyonlara erişim sağlayabilirler.
Ana sınıf | Türetilmiş sınıf | Türetilenden türetilmiş sınıf |
---|---|---|
ios | istream | ifstream |
ostream | ofstream | |
iostream | fstream |
C++'da, bir dosyayı açmak için akışları kullanabiliriz. Giriş, çıkış ve giriş/çıkış olmak üzere üç tür akış vardır. Giriş akışı oluşturmak için akışı ifstream sınıfı olarak, çıkış akışı oluşturmak için akışı ofstream sınıfı olarak ve giriş ve çıkış işlemlerinin her ikisini gerçekleştirmek için akışı fstream sınıfı olarak bildirmemiz gerekir.
Aşağıdaki ifadeler bir adet giriş, bir adet çıkış ve bir adet hem giriş hem de çıkış işlemi yapan bir adet akış oluşturur:
ifstream in; // Giriş akışı ofstream out; // Çıkış akışı fstream io; // Giriş ve çıkış akışı
Bir akış oluşturduktan sonra, akışı bir dosya ile ilişkilendirerek dosya açmak için, her üç akış sınıfının içinde ayrı ayrı tanımlanmış olan open() üye fonksiyonu kullanılır. Open() fonksiyonunun bildirimleri aşağıda gösterilmektedir:
void ifstream::open(const char *dosya-adı, ios::openmode mode = ios::in);
void ofstream::open(const char *dosya-adı, ios::openmode mode = ios::out | ios::trunc);
void fstream::open(const char *dosya-adı, ios::openmode mode = ios::in | ios::out);
Burada, dosya-adı ifadesi dosyanın adını göstermektedir. Bu ifade dosyasının yol tanımlamasını da içerebilir. İkinci parametre olan mode değeri dosyanın açılma yöntemini belirler.
CodeBlocks 17.12 sürümünde ios_base.h başlık dosyasının içinde _Ios_Openmode isimli bir numaralandırma yapılmış ve typedef anahtar kelimesi ile openmode adlı bir veri türü tanımlanmıştır. Sonra, _Ios_Openmode içinde yer alan her bir değer için openmode veri türünden (numaralandırma) statik sabit bir değer oluşturulmuştur.
Dosya açılışında, open() fonksiyonunun ikinci parametresinde aşağıdaki değerlerden bir veya daha fazlası kullanılmalıdır.
// ios_base.h içeriğinde
enum _Ios_Openmode {
_S_app = 1L << 0,
_S_ate = 1L << 1,
_S_bin = 1L << 2,
_S_in = 1L << 3,
_S_out = 1L << 4,
_S_trunc = 1L << 5,
_S_ios_openmode_end = 1L << 16
};
typedef _Ios_Openmode openmode;
static const openmode app = _S_app;
static const openmode ate = _S_ate;
static const openmode binary = _S_bin;
static const openmode in = _S_in;
static const openmode out = _S_out;
static const openmode trunc = _S_trunc;
Başlık dosyasında (ios_base.h) yer alan sabit değerlerin kullanım amaçları aşağıdaki tabloda yer almaktadır:
Mod | Açıklama |
---|---|
ios::app |
|
ios::ate |
|
ios::binary | Dosyanın ikili modda açılmasını sağlar. |
ios::in | Dosyayı veri okuma amacıyla açar. |
ios::out | Dosyayı veri yazma amacıyla açar. |
ios::trunc |
|
Bu değerlerden iki veya daha fazlasını OR işlemcisi ile birleştirerek kullanabiliriz.
Tüm dosyalar ön tanımlı olarak metin modunda açılır. Metin modunda, herhangi bir metin editörü ile oluşturulan DOS metin dosyaları ile kullanılır. Yani, metin modu ASCII karakterlerle birlikte kullanılır. C++ dilinde metin modu, metin dosyalarını satırları tek bir yeni satır karakteri (ASCII 10) ile ayrılmış olarak dikkate alır. Ancak, DOS metin dosyaları, her satırı arasında bir yeni satır (ASCII 10) ve bir satır başı (ASCII 13) karakteri olmak üzere toplam iki karakter ile, diske kaydedilir. C++ dili, metin modunda diskten bir dosya okurken yeni satır ve satır başı karakterlerini tek bir yeni satır karakterine çevirir. Metin akışından diske bir dosyayı kaydederken ise, tek bir yeni satır karakterini, yeni satır ve satır başı karakterlerine çevirir. Bu nedenle, metin akışına gönderilen ifadelerle dosyaya yazılan ifadeler tıpatıp aynı olmayabilir.
İkili modda ise, herhangi bir karakter dönüşümü yapılmaz. Yani, ikili modda diske bir dosya kaydederken veya diskten ikili modda bir dosya aktarırken, dosya içinde yer alan karakterlerde herhangi bir değişiklik yapılmaz. Dosyadan okunan ifadelerle dosyaya gönderilen ifadeler tamamen birbirinin aynıdır.
Dosya ile ilgili işlemleri tamamladıktan sonra bir dosyayı kapatmak için close() fonksiyonu kullanılır. Fonksiyonun genel yapısı aşağıdaki şekildedir:
akış-adı.close();
Fonksiyon herhangi parametre almaz ve herhangi bir değer geri döndürmez.
Dosya açma işlemlerini ifstream, ofstream ve fstream sınıfları içinde yer alan open() üye fonksiyonları veya doğrudan bu sınıfların constructor fonksiyonları ile yapabiliriz.
Dosya açma işlemini ifstream, ofstream ve fstream sınıfları içinde yer alan open() üye fonksiyonları ile yapabiliriz.
Şimdi, dosya açma ve kapatma işlemlerinin open() fonksiyonu ile yapılmasını bir örnek üzerinde incelemeye çalışalım:
#include <iostream>
#include <fstream>
using namespace std;
int main(void)
{
ofstream outfile; // Dosyaya yazma işlemi için akış oluşturma
outfile.open("deneme.txt"); // Dosya açma (.exe dosyanın bulunduğu dizinde oluşturulur.)
outfile.close(); // Dosya kapatma
return 0;
}
Program, bir dosyaya yazma işlemi yapmak için, ofstream sınıfı türünden bir nesne oluşturur. Bu nesne yoluyla ostream sınıfı içindeki open() üye fonksiyonu ile deneme.txt adlı bir dosya oluşturur. Open() fonksiyonunun ikinci parametresinin ön tanımlı değeri ios::out | ios::trunc olduğundan, dosya bu modda açılır. Herhangi bir işlem yapmadan dosyayı kapatır.
Program çalıştırıldığında, .exe dosyanın bulunduğu dizinde deneme.txt adlı bir dosya oluşturulur.
Dosya açma işlemini ifstream, ofstream ve fstream sınıflarının constructor fonksiyonları ile yapabiliriz. Bu sınıfların constructor fonksiyonları open() üye fonksiyonları ile aynı parametreleri alırlar.
Şimdi, dosya açma ve kapatma işlemlerinin constructor fonksiyonları ile yapılmasını bir örnek üzerinde incelemeye çalışalım:
#include <iostream>
#include <fstream>
using namespace std;
int main(void)
{
ofstream outfile("deneme.txt"); // Dosyaya yazma işlemi için akış oluşturma
outfile.close(); // Dosya kapatma
return 0;
}
Program, bir dosyaya yazma işlemi yapmak için, ofstream sınıfı türünden bir nesne oluşturur. Bu nesneyi oluştururken, ostream sınıfı içindeki constructor fonksiyonu ile deneme.txt adlı bir dosya oluşturur. Constructor() fonksiyonunun ikinci parametresinin ön tanımlı değeri ios::out | ios::trunc olduğundan, dosya bu modda açılır. Herhangi bir işlem yapmadan dosyayı kapatır.
Dosya açma işlemi esnasında herhangi bir hata meydana gelip gelmediğini kontrol etmek için, akış değişkeninin aldığı değeri kontrol edebiliriz. Akış değişkeni, dosya normal bir şekilde açılırsa doğru (true), aksi takdirde yanlış (false) bir değer alır.
Şimdi, constructor fonksiyonları ile yapılan dosya açma işlemlerinin hata konrolü ile yapılmasını bir örnek üzerinde incelemeye çalışalım:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main(void)
{
ofstream outfile("deneme.txt"); // Dosyaya yazma işlemi için akış oluşturma
if(!outfile) { // Dosya açma hata kontrolü
cout << "deneme.txt dosyası açma hatası!";
exit(1);
}
outfile.close(); // Dosya kapatma
ifstream infile("deneme2.txt"); // Dosyadan okuma işlemi için akış oluşturma
if(!infile) { // Dosya açma hata kontrolü
cout << "deneme2.txt dosya açma hatası!";
exit(1);
}
infile.close(); // Dosya kapatma (Bu işlem satırı hiç çalışmaz)
return 0;
}
Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:
deneme2.txt dosya açma hatası!
Program, bir dosyaya yazma işlemi yapmak için, ofstream sınıfı türünden outfile adlı bir nesne oluşturur. Bu nesneyi oluşturduktan sonra, nesnenin false değeri taşıyıp taşımadığını kontrol eder. Dosya mevcut olduğundan, if koşulu gerçekleşmez ve dosyayı kapatır. Sonra, bir dosyadan okuma işlemi yapmak için, ifstream sınıfı türünden infile adlı bir nesne oluşturur. Bu nesneyi oluşturduktan sonra, nesnenin false değeri taşıyıp taşımadığını kontrol eder. Dosya mevcut olmadığından, if koşulu gerçekleşir ve koşul içindeki karakter dizisi ekrana yazılır ve programdan çıkış yapılır.
Bir metin dosyasına yazma ve okuma işlemleri, ekrana veri gönderirken ve klavyeden veri okurken kullandığımız, << ve >> işlemcileri ile yapılır. Dosya işlemlerinde fstream, ifstream ve ofstream sınıflarından tanımlanan akış nesneleri bu işlemcilerle birlikte kullanılır.
Bir dosyaya veri yollamak için, önce ofstream sınıfından bir akış nesnesi tanımlayarak dosyayı açmak ve bu işlem esnasında constructor fonksiyonu yoluyla dosya adını belirtmek gerekir. Dosyaya yazma işlemi << işlemcisi ile yapıldıktan sonra dosya kapatılır.
Şimdi, bir dosyaya yazma işlemi yapılmasını bir örnek üzerinde incelemeye çalışalım:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main(void)
{
ofstream outfile("deneme.txt"); // Dosyaya yazma işlemi için akış oluşturma
// Dosya açma hata kontrolü
if(!outfile) {
cout << "deneme.txt dosya açma hatası!" << endl;
exit(1);
}
outfile << "Bilgisayar" << endl;
outfile << 127 << endl;
outfile << 54.789 << endl;
outfile.close(); // Dosya kapatma
return 0;
}
Program, bir dosyaya yazma işlemi yapmak için, dosya adını constructor fonksiyonuna geçirerek, ofstream sınıfı türünden outfile adlı bir akış nesnesi oluşturur. Nesneyi kontrol ederek dosya açma işleminin başarılı olup olmadığını kontrol eder. Dosya mevcut olduğundan, if koşulu gerçekleşmez ve program çalışmasına devam eder. Sonra, akış nesnesi ile << işlemcisini kullanarak bir karakter dizisi, bir int ve bir float değeri dosyaya yazar. Yazma işlemi sona erdikten sonra, close() fonksiyonu ile dosyayı kapatır.
Programın çalışması sona erdikten sonra, bir metin editöründe açtığınızda dosya içeriği aşağıdaki şekilde olacaktır.
Bilgisayar 127 54.789
Programın çalışması sona erdikten sonra, bir hex editörde açtığınızda dosya içeriği aşağıdaki şekilde olacaktır.
Her satır arasında bir satır başı 0x0D (ASCII 13) ve bir yeni satır 0x0A (ASCII 10) karakteri yer alır.
Bir dosyadan veri okumak için, önce ifstream sınıfından bir akış nesnesi tanımlayarak dosyayı açmak ve bu işlem esnasında constructor fonksiyonu yoluyla dosya adını belirtmek gerekir. Dosyadan okuma işlemi >> işlemcisi ile yapıldıktan sonra dosya kapatılır.
>> işlemcisi ile dosyadan veri okuma işlemi yapılırken boşluk karakteri (32 - 0x20) ile karşılaşıldığında, okuma işlemi sona erer.
Şimdi, dosya ile ilgili yazma ve okuma işlemlerinin yapılmasını bir örnek üzerinde incelemeye çalışalım:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main(void)
{
ofstream outfile("deneme.txt"); // Dosyaya yazma işlemi için akış oluşturma
// Dosya açma hata kontrolü
if(!outfile) {
cout << "Yazma amaçlı dosya açma hatası!" << endl;
exit(1);
}
outfile << "Bilgisayar" << endl;
outfile << 127 << endl;
outfile << 54.789 << endl;
outfile.close(); // Dosya kapatma
ifstream infile("deneme.txt"); // Dosyaya yazma işlemi için akış oluşturma
char cdizi[25];
int id;
float fd;
// Dosya açma hata kontrolü
if(!infile) {
cout << "Okuma amaçlı dosya açma hatası!" << endl;
exit(1);
}
infile >> cdizi;
infile >> id;
infile >> fd;
cout << cdizi << endl << id << endl << fd;
infile.close(); // Dosya kapatma
return 0;
}
Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:
Bilgisayar 127 54.789
Program, bir dosyaya yazma işlemi yapmak için, dosya adını constructor fonksiyonuna geçirerek, ofstream sınıfı türünden outfile adlı bir akış nesnesi oluşturur. Nesneyi kontrol ederek dosya açma işleminin başarılı olup olmadığını kontrol eder. Dosya mevcut olduğundan, if koşulu gerçekleşmez ve program çalışmasına devam eder. Sonra, akış nesnesi ile << işaretçisini kullanarak bir karakter dizisi, bir int ve bir float değeri dosyaya yazar. Yazma işlemi sona erdikten sonra, close() fonksiyonu ile dosyayı kapatır.
Program, bir dosyadan okuma işlemi yapmak için, dosya adını constructor fonksiyonuna geçirerek, ifstream sınıfı türünden infile adlı bir akış nesnesi oluşturur. Ayrıca, dosyadan okuyacağı değerleri atamak için bir karakter dizisi, bir int ve bir float değer oluşturur. Nesneyi kontrol ederek dosya açma işleminin başarılı olup olmadığını kontrol eder. Dosya mevcut olduğundan, if koşulu gerçekleşmez ve program çalışmasına devam eder. Sonra, akış nesnesi ile >> işlemcisini kullanarak bir karakter dizisi, bir int ve bir float değeri dosyadan okur ve daha önce oluşturduğu dizi ve değişkenlere atar. Okuduğu değerleri ekrana yazdıktan sonra, close() fonksiyonu ile dosyayı kapatır.
Dosya içinde her satır arasında yer alan bir satır başı 0x0D (ASCII 13) ve bir yeni satır 0x0A (ASCII 10) karakteri, >> işlemcisi ile yapılan okuma esnasında dikkate alınmamaktadır.