← Kursa Dön
📄 Text · 15 min

std::string Kullanımı

Programlamanın belki de en temel yapı taşı metinlerdir. Kullanıcı adı, e-posta adresi, ürün açıklaması — hepsi metin. C++'ta metin işlemek için std::string sınıfını kullanırız. String'i bir boncuk dizisine benzetebilirsin: her boncuk bir karakter ve hepsi bir ipte (bellekte art arda) sıralanmış durumda. İstediğin boncuğu çıkarabilir, yenisini ekleyebilir, dizinin uzunluğunu öğrenebilirsin.

Bu derste std::string ile metin tanımlama, temel operasyonlar, karşılaştırma ve C-string ile farkını öğreneceksin.


String Tanımlama ve Başlatma

std::string kullanmak için <string> başlık dosyasını dahil etmen gerekir:

#include <iostream>
#include <string>

int main() {
    std::string isim = "Ahmet";
    std::string soyisim{"Yilmaz"};          // Uniform initialization
    std::string mesaj("Merhaba Dunya");      // Direct initialization
    std::string bos;                         // Bos string: ""
    std::string tekrar(5, '*');              // "*****" — 5 tane '*'

    std::cout << isim << " " << soyisim << std::endl;
    std::cout << mesaj << std::endl;
    std::cout << "Bos mu: " << bos.empty() << std::endl;
    std::cout << tekrar << std::endl;

    return 0;
}

std::string aslında bir sınıf (class) — int veya double gibi ilkel bir tip değil. Ama C++ onu o kadar doğal kullanılır hale getirmiş ki, ilkel tip gibi hissettiriyor.

String Literalleri

Çift tırnak içindeki metinler aslında C-string (karakter dizisi) olarak başlar ve std::string'e otomatik dönüştürülür:

#include <iostream>
#include <string>
using namespace std::string_literals;  // ""s soneki icin

int main() {
    auto s1 = "Merhaba";       // const char* — C-string!
    auto s2 = "Merhaba"s;      // std::string — 's' soneki
    std::string s3 = "Merhaba"; // std::string — otomatik donusum

    std::cout << s2 << std::endl;
    return 0;
}

💡 İpucu: auto ile string tanımlarken "metin"s şeklinde s soneki ekle. Aksi halde auto tipi const char* (C-string pointer) olarak çıkarır, std::string olarak değil.


String Uzunluğu ve Boşluk Kontrolü

Bir string'in kaç karakter içerdiğini öğrenmek için length() veya size() kullanırsın. İkisi tamamen aynı şeyi yapar:

#include <iostream>
#include <string>

int main() {
    std::string mesaj = "Merhaba Dunya";

    std::cout << "Uzunluk (length): " << mesaj.length() << std::endl;
    std::cout << "Uzunluk (size):   " << mesaj.size() << std::endl;
    std::cout << "Bos mu: " << std::boolalpha << mesaj.empty() << std::endl;

    std::string bos = "";
    std::cout << "Bos string uzunlugu: " << bos.length() << std::endl;
    std::cout << "Bos mu: " << bos.empty() << std::endl;

    return 0;
}

empty() string boşsa true, doluysa false döner. length() == 0 kontrolü yerine empty() kullanmak hem daha okunabilir hem de niyetini daha iyi ifade eder.


Karakterlere Erişim

String içindeki tek bir karaktere erişmenin iki yolu var:

#include <iostream>
#include <string>

int main() {
    std::string isim = "Ahmet";

    // 1. Kose parantez — hizli ama sinir kontrolu yok
    std::cout << "Ilk harf: " << isim[0] << std::endl;
    std::cout << "Son harf: " << isim[isim.length() - 1] << std::endl;

    // 2. at() — sinir kontrolu yapar, guvenli
    std::cout << "2. harf: " << isim.at(1) << std::endl;

    // isim[100];      // Tanimsiz davranis — cokmeyebilir ama tehlikeli
    // isim.at(100);   // std::out_of_range hatasi firlatiir — guvenli

    // Karakter degistirme
    isim[0] = 'E';
    std::cout << "Degismis: " << isim << std::endl;  // Ehmet

    // front() ve back() — ilk ve son karakter
    std::cout << "Ilk: " << isim.front() << std::endl;
    std::cout << "Son: " << isim.back() << std::endl;

    return 0;
}

⚠️ Dikkat: [] operatörü sınır kontrolü yapmaz. Geçersiz bir indekse erişirsen program tanımsız davranır (undefined behavior). Güvenli erişim istiyorsan at() kullan — hatalı indekste exception fırlatır.

String'de Döngü

Bir string'in tüm karakterlerini dolaşmak için range-based for döngüsü en temiz yoldur:

#include <iostream>
#include <string>

int main() {
    std::string kelime = "Merhaba";

    // Range-based for — en temiz yol
    for (char c : kelime) {
        std::cout << c << " ";
    }
    std::cout << std::endl;

    // Indeksle erisim
    for (size_t i = 0; i < kelime.length(); i++) {
        std::cout << kelime[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

String Birleştirme (Concatenation)

İki string'i birleştirmenin birkaç yolu var:

#include <iostream>
#include <string>

int main() {
    std::string ad = "Ahmet";
    std::string soyad = "Yilmaz";

    // 1. + operatoru
    std::string tam_isim = ad + " " + soyad;
    std::cout << tam_isim << std::endl;

    // 2. append() metodu
    std::string selamlama = "Merhaba, ";
    selamlama.append(ad);
    selamlama.append("!");
    std::cout << selamlama << std::endl;

    // 3. += operatoru
    std::string cumle = "Hos";
    cumle += " geldin";
    cumle += " " + ad;
    cumle += "!";
    std::cout << cumle << std::endl;

    return 0;
}

+ operatörü yeni bir string oluşturur, += ve append() mevcut string'e ekler. Çok sayıda birleştirme yapıyorsan += veya append() daha verimlidir çünkü her + yeni bir geçici string oluşturur.

Sayı ve String Birleştirme

C++'ta sayıyı doğrudan string'e ekleyemezsin. std::to_string() ile dönüştürmen gerekir:

#include <iostream>
#include <string>

int main() {
    int yas = 25;
    double boy = 1.75;

    // YANLIS — derlemez
    // std::string mesaj = "Yas: " + yas;

    // DOGRU — to_string kullan
    std::string mesaj = "Yas: " + std::to_string(yas);
    std::cout << mesaj << std::endl;

    std::string bilgi = "Boy: " + std::to_string(boy) + " m";
    std::cout << bilgi << std::endl;
    // Cikti: Boy: 1.750000 m — cok fazla basamak!

    return 0;
}

to_string() ondalıklı sayılarda fazla basamak gösterir. Daha kontrollü çıktı istiyorsan std::ostringstream veya C++20'deki std::format kullanabilirsin.


Alt String Alma — substr()

Bir string'in bir bölümünü almak için substr() kullanırsın:

#include <iostream>
#include <string>

int main() {
    std::string metin = "Merhaba Dunya";

    // substr(baslangic_indeksi, uzunluk)
    std::string ilk_kelime = metin.substr(0, 7);    // "Merhaba"
    std::string ikinci = metin.substr(8);            // "Dunya" — sonuna kadar

    std::cout << "Ilk kelime: " << ilk_kelime << std::endl;
    std::cout << "Ikinci: " << ikinci << std::endl;

    // E-posta ornegi
    std::string email = "ahmet@example.com";
    size_t at_pos = email.find('@');
    std::string kullanici = email.substr(0, at_pos);
    std::string domain = email.substr(at_pos + 1);

    std::cout << "Kullanici: " << kullanici << std::endl;
    std::cout << "Domain: " << domain << std::endl;

    return 0;
}

substr(pos) ikinci parametre verilmezse, pos konumundan string'in sonuna kadar alır. substr(pos, len) ise pos konumundan len karakter alır.


Arama — find()

String içinde bir karakter veya alt string aramak için find() kullanılır:

#include <iostream>
#include <string>

int main() {
    std::string metin = "C++ programlama dili cok guclu bir dildir";

    // Karakter arama
    size_t pos = metin.find('+');
    std::cout << "'+' pozisyonu: " << pos << std::endl;

    // Alt string arama
    size_t dil_pos = metin.find("dili");
    std::cout << "'dili' pozisyonu: " << dil_pos << std::endl;

    // Bulunamazsa std::string::npos doner
    size_t yok = metin.find("Python");
    if (yok == std::string::npos) {
        std::cout << "'Python' bulunamadi" << std::endl;
    }

    // Sondan arama — rfind()
    size_t son_dil = metin.rfind("dil");
    std::cout << "Son 'dil' pozisyonu: " << son_dil << std::endl;

    return 0;
}

find() aranan şeyi bulursa pozisyonunu (indeksini), bulamazsa std::string::npos döner. npos çok büyük bir sayıdır (genelde size_t'nin maksimum değeri). Arama sonucunu her zaman npos ile karşılaştır.

contains(), starts_with(), ends_with() — C++20

C++20 ile birlikte çok kullanışlı üç fonksiyon geldi:

#include <iostream>
#include <string>

int main() {
    std::string dosya = "rapor_2024.pdf";

    // C++20
    if (dosya.starts_with("rapor")) {
        std::cout << "Rapor dosyasi" << std::endl;
    }

    if (dosya.ends_with(".pdf")) {
        std::cout << "PDF formati" << std::endl;
    }

    if (dosya.contains("2024")) {
        std::cout << "2024 yilina ait" << std::endl;
    }

    return 0;
}

Bu fonksiyonlar C++20 öncesinde yoktu ve find() ile elle yapılması gerekiyordu. C++20 kullanabiliyorsan bu fonksiyonlar hayatını kolaylaştırır.


Değiştirme — replace() ve erase()

String'in bir bölümünü değiştirmek veya silmek için:

#include <iostream>
#include <string>

int main() {
    std::string metin = "Merhaba Dunya";

    // replace(pozisyon, uzunluk, yeni_metin)
    metin.replace(8, 5, "C++");
    std::cout << metin << std::endl;  // "Merhaba C++"

    // Belirli bir kelimeyi bul ve degistir
    std::string cumle = "Bugün hava çok güzel, çok güzel bir gün";
    size_t pos = cumle.find("çok güzel");
    if (pos != std::string::npos) {
        cumle.replace(pos, 10, "harika");  // UTF-8'de dikkat: byte sayisi
    }
    std::cout << cumle << std::endl;

    // erase — silme
    std::string test = "Merhaba Dunya";
    test.erase(7);  // 7. indeksten sonrasini sil
    std::cout << test << std::endl;  // "Merhaba"

    // insert — ekleme
    test.insert(7, " Guzel Dunya");
    std::cout << test << std::endl;  // "Merhaba Guzel Dunya"

    return 0;
}

replace() yerinde değişiklik yapar, yeni bir string oluşturmaz. erase() karakterleri siler, insert() belirtilen pozisyona ekler.


String Karşılaştırma

String'leri karşılaştırmak basittir — ==, !=, <, > operatörleri çalışır:

#include <iostream>
#include <string>

int main() {
    std::string a = "Ahmet";
    std::string b = "Ahmet";
    std::string c = "Mehmet";

    // Esitlik
    if (a == b) {
        std::cout << "a ve b esit" << std::endl;
    }

    if (a != c) {
        std::cout << "a ve c farkli" << std::endl;
    }

    // Sirasal karsilastirma (leksikografik — sozluk sirasi)
    if (a < c) {
        std::cout << "'" << a << "' sozlukte '" << c << "' den once gelir" << std::endl;
    }

    // compare() metodu — daha detayli kontrol
    int sonuc = a.compare(c);
    if (sonuc < 0) std::cout << a << " < " << c << std::endl;
    else if (sonuc > 0) std::cout << a << " > " << c << std::endl;
    else std::cout << a << " == " << c << std::endl;

    return 0;
}

String karşılaştırması leksikografiktir — yani sözlük sırasına göre. "Apple" < "Banana" çünkü 'A' harfi 'B'den önce gelir (ASCII değeri küçük). Büyük/küçük harf duyarlıdır: "ahmet" != "Ahmet".

💡 İpucu: Büyük/küçük harf duyarsız karşılaştırma için standart bir fonksiyon yok. Karşılaştırmadan önce her iki string'i de küçük harfe çevirmen gerekir.


C-string vs std::string

C dilinden kalma karakter dizileri (C-string) ile std::string arasında önemli farklar var:

#include <iostream>
#include <string>
#include <cstring>  // C-string fonksiyonlari icin

int main() {
    // C-string — null-terminated karakter dizisi
    const char* c_str = "Merhaba";
    char c_arr[] = "Dunya";

    // std::string
    std::string cpp_str = "Merhaba";

    // Uzunluk
    std::cout << "C-string uzunluk: " << strlen(c_str) << std::endl;
    std::cout << "string uzunluk: " << cpp_str.length() << std::endl;

    // Birlestirme
    // strcat ile C-string birlestirme — zahmetli ve tehlikeli
    char buffer[50];
    strcpy(buffer, c_str);
    strcat(buffer, " ");
    strcat(buffer, c_arr);
    std::cout << "C-string: " << buffer << std::endl;

    // std::string ile — kolay ve guvenli
    std::string sonuc = cpp_str + " " + c_arr;
    std::cout << "string: " << sonuc << std::endl;

    return 0;
}

Farklar Tablosu

ÖzellikC-string (char[])std::string
Boyut yönetimiManuelOtomatik
Taşma riskiVar (buffer overflow)Yok
Birleştirmestrcat — tehlikeli+ operatörü — kolay
Karşılaştırmastrcmp== operatörü
Uzunlukstrlen (O(n))length() (O(1))
BellekStack veya statikOtomatik yönetim

⚠️ Dikkat: Yeni C++ kodu yazarken neredeyse her zaman std::string kullan. C-string sadece C kütüphaneleriyle çalışırken veya düşük seviyeli işlemlerde gereklidir. std::string'den C-string'e dönüşüm için .c_str() metodunu kullanabilirsin.

Dönüşümler

#include <iostream>
#include <string>

int main() {
    // C-string -> std::string (otomatik)
    std::string s = "Merhaba";

    // std::string -> C-string
    const char* c = s.c_str();
    std::cout << c << std::endl;

    // String -> sayi
    std::string sayi_str = "42";
    int sayi = std::stoi(sayi_str);         // string to int
    double ondalik = std::stod("3.14");     // string to double

    std::cout << "Int: " << sayi << std::endl;
    std::cout << "Double: " << ondalik << std::endl;

    // Sayi -> string
    std::string tekrar = std::to_string(sayi);
    std::cout << "String: " << tekrar << std::endl;

    return 0;
}

stoi (string to int), stod (string to double), stof (string to float) — bunlar string'den sayıya dönüşüm fonksiyonlarıdır. Geçersiz girişte std::invalid_argument exception fırlatırlar.


Kullanıcıdan String Okuma

cin >> ile string okurken boşlukta durur. Satırın tamamını okumak için getline kullanırsın:

#include <iostream>
#include <string>

int main() {
    std::string isim;
    std::string tam_ad;

    std::cout << "Isim girin: ";
    std::cin >> isim;  // Boslukta durur: "Ahmet Yilmaz" -> sadece "Ahmet"

    std::cin.ignore();  // Buffer'daki newline'i temizle

    std::cout << "Tam ad girin: ";
    std::getline(std::cin, tam_ad);  // Satirin tamamini okur

    std::cout << "Isim: " << isim << std::endl;
    std::cout << "Tam ad: " << tam_ad << std::endl;

    return 0;
}

💡 İpucu: cin >> ve getline art arda kullanırken cin.ignore() çağırmayı unutma. cin >> satır sonu karakterini (\n) buffer'da bırakır ve getline onu okuyup boş string döner.


String ve Bellek — Kısa String Optimizasyonu (SSO)

std::string normalde heap'te bellek ayırır. Ama kısa string'ler için bir optimizasyon vardır: SSO (Small String Optimization). Kısa string'ler (genelde 15-22 karakter altı) doğrudan string nesnesinin içinde saklanır, heap'e gidilmez.

#include <iostream>
#include <string>

int main() {
    std::string kisa = "Merhaba";        // SSO — heap kullanilmaz
    std::string uzun = "Bu cok uzun bir string ki heap'te saklanacak kadar buyuk";

    std::cout << "Kisa kapasite: " << kisa.capacity() << std::endl;
    std::cout << "Uzun kapasite: " << uzun.capacity() << std::endl;

    // reserve — onceden yer ayir
    std::string verimli;
    verimli.reserve(1000);  // 1000 karakter icin yer ayir
    // Artik 1000 karaktere kadar ekleme heap reallocate gerektirmez

    return 0;
}

Çok sayıda string birleştirme yapacaksan, reserve() ile önceden yer ayırmak performansı artırır. Her birleştirmede string'in boyutu büyüyünce yeniden bellek ayırma (reallocation) olabilir ve bu maliyetlidir.


Faydalı String Fonksiyonları Özet Tablosu

FonksiyonAçıklamaÖrnek
length() / size()Karakter sayısıs.length()
empty()Boş mu kontrolüs.empty()
at(i) / [i]i. karaktere erişims.at(0)
front() / back()İlk / son karakters.front()
substr(pos, len)Alt strings.substr(0, 5)
find(str)Arama (pozisyon döner)s.find("abc")
rfind(str)Sondan aramas.rfind("abc")
replace(pos, len, str)Değiştirmes.replace(0, 3, "yeni")
erase(pos, len)Silmes.erase(5, 3)
insert(pos, str)Eklemes.insert(5, "xxx")
append(str) / +=Sona eklemes.append("ek")
c_str()C-string'e dönüştürs.c_str()
starts_with(str)Başlangıç kontrolü (C++20)s.starts_with("ab")
ends_with(str)Bitiş kontrolü (C++20)s.ends_with(".pdf")
contains(str)İçerik kontrolü (C++23)s.contains("xyz")

Özet

  • std::string C++'ta metin işlemenin standart ve güvenli yoludur — C-string yerine bunu kullan

  • `{}` ile başlatma, length() ile uzunluk, at() ile güvenli karakter erişimi sağlanır

  • `+` ve `+=` ile string birleştirme yapılır; sayıları eklemek için std::to_string() kullan

  • `find()` arama yapar, bulamazsa std::string::npos döner — her zaman kontrol et

  • `substr()` alt string alır, `replace()` değiştirir, `erase()` siler

  • Kullanıcı girdisi okurken `getline()` satırın tamamını alır; cin >> boşlukta keser