9 Eylül 2019 Pazartesi

std::string Sınıfı

Giriş
Açıklaması şöyle
std::string is a convenience typedef onto std::basic_string<char>. There are more such typedefs for different underlying character types.
String için std::u16string sınıfı da tanımlı. Char yerine 2 byte'lık char16_t tutması dışında geri kalan herşey aynı.

std::string 103'ten fazla metod sunarak acaip bir rekor kırıyor.

Bellek Alanı
std::string Bellek Alanı yazısına taşıdım.

String ve char
C++ standardı char tipi signed veya unsigned olacak diye bir kural koymamış. Ancak string sınıfının < ve == operatörleri unsigned olacak denilmiş.
[char.traits.specializations.char]: “The two-argument members eq and lt shall be defined identically to the built-in operators == and < for type unsigned char .”
Bu yüzden aşağıdaki < karşılaştırması tüm derleyicilerde çalışırken, ikinci karakter karşılaştırması bazılarında çalışmayabilir.
include <iostream>
#include <string>

using namespace std;

int main() 
{
    std::string a = "\x7f";
    std::string b = "\x80"; //128'e eşittir
    cout << (a < b) << endl;
    cout << (a[0] < b[0]) << endl; //Signed ise 0-127 arasıdır.

    return 0;
}
Constructor metodları
Constructor metodları yazısına taşıdım.

String Accessor Metodları
c_str() ve data() olarak iki metod sunuyor. İmzaları şöyle
const charT* c_str() const noexcept;
const charT* data() const noexcept;
Açıklaması şöyle. Ancak C++11'den sonra ne değişmiş anlayamadım.
Return value
Pointer to the underlying character storage.
data()[i] == operator[](i) for every i in [0, size()) (until C++11)
data() + i == &operator[](i) for every i in [0, size()] (since C++11)
std::string c_str() metodu yazısına taşıdım.
std::string data() Metodu yazısına taşıdım.

Char Accessor Metodları
std::string Char Accessor Metodları yazısına taşıdım.

String Karşılaştırma
std::string Karşılaştırma yazısına taşıdım.

Operator Metodları
operator = metodu
İmzaları şöyle
basic_string& operator=(const basic_string& str);
basic_string& operator=(basic_string&& str)
 noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
          allocator_traits<Allocator>::is_always_equal::value);
basic_string& operator=(const charT* s);
basic_string& operator=(charT c);
basic_string& operator=(initializer_list<charT>);
operator= metodu - char
İmzası şöyle.
string& operator= (char ch );
Bu operatör biraz tehlikeli çünkü char'a çevrilebilen herhangi bir değer string'e atanabilir.
Örnek
Şöyle yaparız.
std::string my_string("");
unsigned int my_number = 98;
my_string = my_number;
Eksi int değerler de char'a çevrilebiliyor. Yani hataya müsait.
std::string foo;
foo = -1; // why is the compiler not complaining about this?
operator=  metodu - char *
İmzası şöyle
basic_string& operator=(const charT* s);
Örnek
Şöyle yaparız.
std::string str = "Some quite long string, which needs a lot of memory";
str = "";
str = "A new quite long but smaller string";
operator = metodu - Move Assignment
İmzası şöyle.
basic_string& operator=(basic_string&& str)  noexcept(/*...*/)
Açıklaması şöyle.
Effects: Move assigns as a sequence container, except that iterators, pointers and references may be invalidated.
operator + metodu
Metodun içi şöyle
/// note reference return type
std::string& operator +=(char c) 
{
  this->append(c);
  return *this;
}

// note value return type
std::string operator +(char c) const
{
  std::string tmp = *this;
  tmp += c; // or just tmp.append(c) directly
  return tmp;
}
operator += metodu
İmzası şöyle
std::string::operator +=(char);         // str += 'a';
const char * için imzası şöyle
std::string::operator +=(const char*);  // str += "abc";
Bir diğer imza gösterimi şöyle
template <typename CharT>
class basic_string{
  basic_string& operator+=(CharT _c);
};
char'a çevirilebilen herhangi bir değer string'e atanabilir.
Örnek string'e int veya char eklenebilir
Şöyle yaparız.
str +=1;//ok
str += '\0';//ok...expected
str +=INT_MAX;//ok
str +=int(INT_MAX);//still ok...what?
Örnek - string'e int eklenebilir
Şöyle yaparız.
std::string s;
s += 2;     // compiles correctly
Örnek - += operator ve global operator + farklıdır
Şu iki kod farklı sonuçlar verir.
string s1 = "abcdefghijklmnopq";
string s2 = "";
string s3 = "";

s3+=s1[4];
s3+=s1[5];
s3+=s1[6];
cout << s3 << endl;  // Expected behaviour

s2=s1[4]+s1[5]+s1[6];
cout << s2 << endl;  // ?????
operator += ile "global operator +()" farklı şeylerdir. global operator +'nın imzası şöyledir.
template <typename CharT>
  basic_string<CharT>
  operator+(const basic_string<CharT>& lhs, CharT rhs);
Şöyle yaparız.
s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only
Sağ tarafa char veya char'a çevrilebilen string beklediği için şu kod derlenmez.
std::string s;
s = s + 2;  // compiler error
Diğer metodlar
append metodu
C tarzı string'i ekler. C tarzı string null karakteri ile bittiği için aşağıdaki kod aslında hiç bir şey yapmaz.
std::string str = "...";
str.append("\0");
null karakteri eklemek için şöyle yaparız.
str.append("\0", 1);
assign metodu
Verilen right isimli parametreyi kendi sınıfıma taşır. İmzası şöyledir. Çağrı sonunda parametre undefined state halinde kalır.
basic_string& assign( basic_string&& right );
Şöyle çağırabilirim.
string final; 
string tmp = ...;
final.assign(std::move(tmp));
back metodu
Aynı vector'deki gibi en sondaki eleman erişim sağlar.
std::string str ("Some string");
cout << str.back() // Çıktı olarak g verir.
empty metodu
Metodun içi şöyle
bool empty() const _NOEXCEPT
{   // test if sequence is empty
  return (this->_Mysize == 0);
}
erase metodu
Belirtilen indeksten itibaren, belirtilen sayı kadar karakter siler. İkinci parametre npos olsa bile sorunsuz çalışır.
std::string className = ...;
const size_t index = className.find("::");
if (endOfClassNamePos != std::string::npos)
  className.erase(index, std::string::npos);
find metodu
std::string Arama Metodları yazısına taşıdım.

find_first_not_of
std::string Arama Metodları yazısına taşıdım.

insert metodu
string sınıfı vector'e çok benzediği için belirtilen konumdan sonra karakter eklenmesi sağlanabilir. Aşağıdaki kod araya bir karakter ekler. İkinci parametre bir string tipindendir.
str.insert(i+1, "_");
veya şu şekilde yapılabilir. İkinci parametre karakter tipindendir.
str.insert(i+1, 1, '_');
length metodu
length() metodu std::string::size_type  döner. Bu genellikle unsigned int'tir ama olmak zorunda değildir.

npos alanı
Bu alan şöyle tanımlı.
static const size_type  npos = static_cast<size_type>(-1);
resize metodu
Şöyle yaparız.
str.resize(n);
size metodu
length() ile aynı şeydir. Açıklaması şöyle.
If any operation would cause size() to exceed max_size() , that operation throws an exception object of type length_error.
substr metodu
substr() metodu verilen index'ten sonra belirtilen uzunluk kadar karakterleri döndürür.
std::string testStr = "abcdefghijklmnopqrstuvwxyz{";
size_t index = 1;
std::string subStr = testStr.substr(0, index);
Eğer uzunluk belirtilmezse verilen index'ten sona kadar olan karakterleri döndürür. Normalde string:::npos kullanmaya gerek yoktur ancak daha anlaşılır olsun diye böyle yazdım.
std::string subStr = testStr.substr(index, std::string::npos);
substr() geçici bir string döndürür. Bu string'e yeni bir değer atamak gibi anlamsız işler de yapılabilir. Şöyle yaparız.
string s = "abcdefghijkl";

s.substr(2,3) = "foo";


Hiç yorum yok:

Yorum Gönder