GİRİŞ/ÇIKIŞ
C++ ‘ın Giriş/Çıkış (Input/Output) sistemi akımlar (stream) üzerinde hareket eder. Akım ise bilgiyi üretir yada alır. Akımı sanal bir cihaz gibide düşünebiliriz. Farklı aygıtlara aynı arabirimi kullanarak ulaşabiliriz. C++ ‘daki kendiliğinden açılan akımlar; cout, cin, clog ve cerr ‘dir. Cerr standart hatadır, clog ise önbellekli standart hatadır. Geniş karakter akımlarını desteklemek için 16 bitlik sürümleri olan wcout, wcin, wclog ve wcerr kullanılabilir.
I/O sınıfları ŞABLON sınıflar sistemi ile başlar. Şablon sınıf işleyeceği verileri belirlemeden sınıfın biçimini tanımlayan sınıftır. C++ iki şablon sınıf hiyerarşisi üzerine kurulmuştur. Alt seviyeli I/O tarafından türetilmiş basic_streambuf ‘dır. basic_streambuf alt seviyeli giriş çıkışları destekler. İkinci sınıf hiyerarşisi ise basic_ios üst seviyelidir. basic_ios biçimlendirme, I/O akım durum bilgisi ve hata denetimini gerçekleştirir. Aşağıda 8 bitlik karakterler için şablon sınıfları ios, streambuf, ostream, iostream, istream, ofstream, ifstream, fstream ‘dir.
Akımlar ise bilgilerin biçinlerini kontrol eden format karakterlerine sahiptir. Aşağıdaki bayraklar ios sınıfı içerisinde fmtflags isminde bir bitmask ‘da deklare edilir.
//bios.h
class _CRTIMP ios {
public:
enum {
skipws = 0x0001,
left = 0x0002,
right = 0x0004,
internal = 0x0008,
dec = 0x0010,
oct = 0x0020,
hex = 0x0040,
showbase = 0x0080,
showpoint = 0x0100,
uppercase = 0x0200,
showpos = 0x0400,
scientific = 0x0800,
fixed = 0x1000,
unitbuf = 0x2000,
stdio = 0x4000
};
static const long basefield; // dec | oct | hex
static const long adjustfield; // left | right | internal
static const long floatfield; // scientific | fixed
skipws: Boşluk karakterleri.
left: Çıkış soldan hizalanır.
right: Çıkış ssağdan hizalanır.
internal: nümerik değerin işaret ile arasındaki yerlere boşluk ekler.
dec = 0x0010,
oct = 0x0020,
hex = 0x0040,
showbase: Nümerik değerlerin tabanı görülebilir.
Showpoint: Nümerik değerlere nokta ve sıfır koyar.
uppercase :1 değerini alırsa Büyük harf.
showpos: Pozitif sayının başına + koyar.
scientific :1 değerini alırsa bilimsel notasyonla gösterir.
fixed = 0x1000,
unitbuf: Tampon bellek her eklemede taşar.
Boolalpha: True ve False kullanılarak giriş/çıkış yapılabilir.
Ayrıca bayrakların biçimlendirilmesinde aşağıdaki fonksiyonlarda kullanılır.
width(): Alan genişliği.
precision(): Doğruluk.
fill(): doldurma karakteri.
Format bayrağına değer vermek için ios ‘un üyesi setf() fonksiyonu kullanılmaktadır. Kullanımı,
fmtflags setf(fmtflags flags);
Format bayrağının bir önceki değerini döndürür. Ayrıca flags tarafından belirlenen bayrakların değerini on yapar. Örneğin,
stream.setf(ios::showbase);
stream.setf(ios::showpoint | ios::oct);
İkinci örnekte birden fazla bayrağın değeri değiştirldi, stream etkilenmek istenilen akımdır.
void unsetf(fmtflags flags);
yazılırsa birden fazla bayrağın değerleri sıfırlanmış olur. Tüm format bayraklarının değerinin değiştirilmesi istenirse,
fmtflags flags(fmtflags f);
yazılır.Format bayrağının değerini bilmek için,
fmtflags flags();
yazılır.
Örnek,
#include <iostream>
using namespace std;
class gc{
public:
void format();
};
void gc::format(){
cout << 495.748 <<'\n';
cout << 99 << '\n';
cout << 88.78<< "\n";
cout.unsetf(ios::dec);
cout.setf( ios::scientific);
cout << 495.748 <<'\n';
cout.setf(ios::showpos);
cout << 99 << '\n';
cout. setf(ios::fixed |ios::showpoint );
cout << 88.78<< "\n";
}
void main()
{
gc ob;
ob.format();
}
Çıktısı;
495.748
99
88.78
4.957480e+002
+99
+88.7800
Başaka bir örnek,
#include <iostream>
using namespace std;
class gc{
public:
void format();
};
void gc::format(){
cout.width(6);
cout.precision(6);
cout << 3.14 << endl;
cout.width(6);
cout.precision(2);
cout << 3.14 << endl;
cout.width(6);
cout << "IKU" << endl;
cout.fill('@');
cout.width(6);
cout << "IKU" << endl;
cout.setf(ios::left);
cout.width(6);
cout << "IKU" << endl;
}
void main()
{
gc ob;
ob.format();
}
Başka bir yöntem ise I/O manipülatörlerinin kullanılmasıdır. Aşağıda manipülatörler verilmiştir. <iomanip> ‘in programa dahil edilmesi gerekir.
// iomanip.h
.
.
inline ios& __resetiosflags(ios& s, long _flg) { s.setf(0,_flg); return s; }
inline ios& __setfill(ios& s, int _fc) { s.fill((char)_fc); return s; }
inline ios& __setiosflags(ios& s, long _flg) { s.setf(_flg); return s; }
inline ios& __setprecision(ios& s, int _pre) { s.precision(_pre); return s; }
inline ios& __setw(ios& s, int _wid) { s.width(_wid); return s; }
inline SMANIP(long) resetiosflags(long _l) { return SMANIP(long)(__resetiosflags, _l); }
inline SMANIP(int) setfill(int _m) {return SMANIP(int)(__setfill, _m); }
inline SMANIP(long) setiosflags(long _l) {return SMANIP(long)(__setiosflags, _l); }
inline SMANIP(int) setprecision(int _p) {return SMANIP(int)(__setprecision, _p); }
inline SMANIP(int) setw(int _w) { return SMANIP(int)(__setw, _w); }
Örneğin,
#include <iostream>
#include <iomanip>
using namespace std;
class gc{
public:
void format();
};
void gc::format(){
cout << hex <<99 << endl;
cout << setfill('@') << setw(6);
cout << 99 << endl;
}
void main()
{
gc ob;
ob.format();
}
Çıkış operatörü (<<) inserter ve giriş operatörü (>>) extractor oluşturarak aşırı yüklenebilir. Çıkış akımına bilgi eklenilmiş olur. Kullanımı,
ostream &operator << (ostream &stream, sınıf_adı nesne)
{
...
return stream;
}
ostream tipinde bir nesneyi işaret ediyor ve stream ise bie çıkış akımını ifade ediyor.
Extractor oluşturulması,
istream &operator >> (istream &stream, sınıf_adı nesne)
{
...
return stream;
}
Özel manipülatör fonksiyonu oluşturulabilir,
ostream &manipülator_adı(ostream &stream)
{
....
return AKIM;
}
istream &manipülator_adı(istream &stream)
{
....
return AKIM;
}
Örneğin,
#include <iostream>
using namespace std;
class adres {
public:
int x;
adres() { x = 0; }
adres(int i) { x = i;}
};
ostream &operator<<(ostream &stream, adres ob)
{
stream << ob.x << " .Sokak " ;
return stream;
}
int main()
{
adres ob(2);
cout << ob ;
return 0;
}