Menu

C++ String'ler: std::string Temelleri, Metotlar ve Tuzaklar

C++'ta std::string nasıl kullanılır - metni güvenle oluşturma, birleştirme, arama ve dilimleme; ayrıca gerçek işler için neredeyse hiçbir zaman ham bir char* istemeyişinizin nedeni.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

std::string: Kendini Yöneten Metin

Önceki sayfada akıllı işaretçilerin bir nesnenin bir kaynağa sahip olmasını ve onu otomatik olarak temizlemesini nasıl sağladığını görmüştünüz. std::string aynı fikrin metne uygulanmış halidir: bir karakter tamponuna sahiptir, sen ekleme yaptıkça onu büyütür ve string kapsamdan çıktığında onu serbest bırakır. Asla new çağırmaz, asla bayt saymaz ve asla eksik bir null sonlandırıcı için endişelenmezsin.

Kullanmak için <string>'i dahil et. Sınıf std ad alanında bulunur.

Bu + operatörü gerçek bir iş yapıyor - her iki parçaya yetecek kadar büyük yeni bir tampon ayırır ve onları içine kopyalar. Ham bir char* ile strcpy ve strcat'e başvurur ve tamponunun yeterince büyük olduğunu umardın. std::string o hata sınıfının tamamını ortadan kaldırır.

String'leri Oluşturma ve Birleştirme

+ ile birleştirebilirsin, ama bir string'i yerinde büyütmenin asıl iş atı +='dir. Her seferinde bambaşka bir string üretmek yerine mevcut tampona ekleme yapar; bu da döngüler içinde önem taşır.

Sık görülen bir sürpriz: +, operandlardan en az birinin zaten bir std::string olmasını gerektirir. İki string literali yalnızca const char*'tır, bu yüzden "a" + "b" derlenmez - iki ham işaretçi için operator+ yoktur. Önce bunlardan birini string yap:

string s = "a" + "b";              // error: can't add two const char*
string s = string("a") + "b";      // fine - left side is a std::string
string s = "a"s + "b";             // fine in C++14+, the "s" literal suffix

Son biçimin <string>'ten gelen s son ekini kullandığına dikkat et (using namespace std::string_literals;); bu, bir literali doğrudan bir std::string'e dönüştürür.

Bir String'in İçine Erişmek

Bir std::string, char kapsayıcısı gibi davranır, bu yüzden onu indeksleyebilir, üzerinde döngü kurabilir ve ondan parçalar isteyebilirsin.

substr(pos, len), orijinalden kopyalanmış bambaşka bir string döndürür; kaynağı değiştirmez. Sınırlara dikkat et: 5 karakterlik bir string üzerinde word[10] tanımsız davranıştır - hata fırlatmaz, sadece çöp veri okur. std::out_of_range fırlatan denetimli bir erişim istiyorsan, word[10] yerine word.at(10) kullan.

Bir başka klasik tuzak: .size() işaretsiz bir tip (size_t) döndürür. for (size_t i = word.size() - 1; i >= 0; --i) gibi geriye doğru bir döngü yazmak asla bitmez, çünkü işaretsiz bir i asla sıfırın altına inemez - sarmalanıp devasa bir sayıya döner. Bir string'i tersten dolaşman gerektiğinde işaretli bir indeks kullan veya koşulu yeniden düzenle.

Arama ve Değiştirme

find bir alt dizgiyi veya karakteri bulur ve başlangıç indeksini döndürür. Hedef mevcut değilse, özel sabit std::string::npos'u döndürür - find'in -1 döndürdüğünü varsaymak yerine her zaman ona karşı karşılaştır.

Metni yerinde değiştirmek için replace(pos, len, text) bir aralığı yeni içerikle (farklı uzunlukta olabilir) takas eder; insert/erase ise parça ekler veya çıkarır:

String'ler ve Sayılar

Metin ve sayılar kendiliğinden dönüşmez - "42", 42 tam sayısı değil, üç karakterdir. Standart kütüphane sana her iki yönde de dönüştürme işlevleri verir. Metni sayıya ayrıştırmak için stoi, stod ve arkadaşlarını, diğer yöne gitmek için to_string'i kullan.

Burada iki tuzak var. Birincisi, stoi("abc") std::invalid_argument fırlatır, bu yüzden güvenilmeyen girdiyi try/catch ile koru. İkincisi, to_string(3.99) tam 3.990000'ı verir - hassasiyet ve biçimlendirme üzerinde kontrol istiyorsan, bu, string stream'lerin işidir ve tam da bir sonraki gideceğimiz yer orası.

try {
    int n = std::stoi(userInput);
} catch (const std::invalid_argument&) {
    std::cout << "That wasn't a number.\n";
}

Sıradaki: Girdi ve Çıktı

Bunca zamandır string'leri cout ile yazdırıyorsun, ama onları kullanıcıdan geri okumanın kendine has sürprizleri var - cin >> name ilk boşlukta durur, bu yüzden "Ada Lovelace" gibi bütün bir satır için onun yerine std::getline gerekir. Sonraki sayfa C++ girdi ve çıktısını gerektiği gibi ele alıyor: akış operatörleri, bütün satırları okuma ve artakalan satır sonlarına takılmadan >> ile getline'ı bir arada kullanma.

Sıkça Sorulan Sorular

C++'ta std::string ile char* arasındaki fark nedir?

std::string, kendi belleğine sahip olup onu yöneten, gerektikçe büyüyen ve otomatik olarak temizlenen bir sınıftır. char* ise sonunda bir '\0' sonlandırıcı bulunan, karakterlere işaret eden ham bir işaretçidir - tamponu, uzunluğu ve yaşam süresini kendiniz yönetirsiniz. Neredeyse her şey için std::string'i tercih edin; tampon taşması ve sarkan işaretçi hatalarının tüm kategorilerini ortadan kaldırır.

C++'ta bir string'in uzunluğunu nasıl alırsınız?

Bir std::string üzerinde .size() veya onun takma adı .length() çağırın: name.size() karakter sayısını size_t olarak döndürür. İkisi de aynı değeri döndürür; size() daha yaygın bir kullanımdır çünkü diğer tüm STL kapsayıcılarıyla uyumludur.

C++'ta bir string'i sayıya nasıl dönüştürürsünüz?

int için std::stoi, double için std::stod ve benzerlerini (stol, stof) kullanın. Örnek: int n = std::stoi("42");. Metin bir sayı değilse bu işlevler std::invalid_argument fırlatır, bu yüzden girdiye güvenilmiyorsa onları bir try/catch içine alın.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA