basic_string sınıf şablonunun en önemli içsel türlerinden (nested types) biri size_type türüdür. size_type türünün bildirimi şu şekildedir:
1 2 3 4 5 6 7 8 9 10 |
namespace std { template <typename CharType, typename TraitsType = char_traits<CharType>, typename AllocatorType = allocator<CharType> > class basic_string { public: // typedef typename Allocator::size_type size_type; static const size_type npos = -1; }; |
Bildirimden de görüldüğü gibi aslında size_type üçüncü şablon tür parametresinin (Allocator Type) türünün yine size_type isimli içsel türüne eş isimdir ve işaretsiz bir tamsayı türüne karşılık gelir. string sınıfı için bu tür standart kütüphanenin size_t türüdür.
Yani eğer string sınıfını kullanıyorsak size_type türü yerine doğrudan size_t türünü kullanabiliriz.
basic_string sınınf şablonunun arayüzünde size_type türü bazı işlevlerin geri dönüş değeri türü ve bazı işlevlerin de parametre değişkeninin/değişkenlerinin türü olarak karşımıza çıkar. Birkaç üye işlevden örnek verelim:
1 2 3 4 5 |
size_type size()const; size_type length()const; size_type capacity()const; void string::reserve(size_type num); size_type find(CharType c); |
size_type türü aşağıdaki verilerin türüdür:
i) Yazı uzunluğunun türü
ii) Yazının bir karakterinin indisinin türü
iii) Adet (tane) türü.
Herhangi bir işlev bizden yukarıdaki değerlerden birini istiyor ise ilgili parametre değişkeni size_type türündendir. Yine herhangi bir üye işlev bize bu değerlerden birini veriyor ise işlevin geri dönüş değeri bu tür olacaktır. Örneğin string sınıfının arama yapan tüm işlevlerinin geri dönüş değeri aranan öğeye ilişkin indis değeri olduğundan tüm arama işlevlerinin geri dönüş değerlerisize_type türündendir.
string sınıfının const static public veri öğesi olan npos ilgili türün en büyük tamsayı değeridir:
1 |
const static size_type npos = -1; |
Peki neden npos isimli bir const static veri öğemiz var? npos değeri iki temel amaçla kullanılır.
i) size_type türünün en büyük değeri olduğundan hiçbir yazının hiçbir karakterinin indisi npos değeri olamaz. Çünkü npos bir yazının olabilecek en büyük uzunluk değeridir. (Yazının ilk karakterinin indisinin 0 olduğunu hatırlatalım). Bu durumda arama işlevleri aranan değerin yazı içinde bulunmaması durumunda özel bir değer olarak npos değerine geri dönerler.
ii) basic_string sınıfının bazı işlevlerinde şöyle bir parametre çifti vardır:
1 |
size_type idx, size_type n |
İşlev yaptığı işi yazının idx indisli öğesinden başlayarak n karakteri üstünde gerçekleştirir. Bu tür işlevlere n değeri olarak idx indisiyle başlayan yazının karakter sayısından daha yüksek bir değerin geçilmesi çalışma zamanı hatasına neden olmayan normal ve olağan bir durumdur. Bu durumda söz konusu işlem yazının geriye kalan karakterlerin tamamı üzerinde yapılır. Eğer böyle bir işlevin işini idx indisinden başlayarak geriye kalan tüm karakterler üzerinde yapmasını istersek işleve n değeri olarak geçebileceğimiz ve her zaman doğru olma garantisindeki tek değer npos değeridir.
string sınıfının erase işlevlerinden biri bu duruma örnek olarak verilebilir:
1 |
string &erase(size_type idx = 0, size_type n = npos); |
Bu işlev stringin idx indisli öğesinden başlayarak n tane karakteri stringden siler. n için varsayılan değer olarak npos değerinin seçildiğini görüyorsunuz. Yani işlevin ikinci parametre değişkenine bir değer geçmezsek npos değerini geçmiş oluyoruz. Bu durumda belirtiğimiz idx değerinden başlayarak geriye kalan tüm karakterler silinmiş oluyor.
Aşağıdaki kod npos veri öğesinin her iki kullanımını da gösteriyor. Kodda file_name stringinin tuttuğu yazıdaki eğer nokta karakteri var ise son nokta karakteri ve bunu izleyen tüm karakterler siliniyor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <string> using namespace std; int main() { string file_name; cout << "dosya ismini giriniz: "; cin >> file_name; auto idx = file_name.rfind('.'); if (idx != string::npos) { file_name.erase(idx); cout << "(" << file_name << ")" << endl; } return 0; } |