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:
autoile string tanımlarken"metin"sşeklindessoneki ekle. Aksi haldeautotipiconst char*(C-string pointer) olarak çıkarır,std::stringolarak 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 istiyorsanat()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
| Özellik | C-string (char[]) | std::string |
|---|---|---|
| Boyut yönetimi | Manuel | Otomatik |
| Taşma riski | Var (buffer overflow) | Yok |
| Birleştirme | strcat — tehlikeli | + operatörü — kolay |
| Karşılaştırma | strcmp | == operatörü |
| Uzunluk | strlen (O(n)) | length() (O(1)) |
| Bellek | Stack veya statik | Otomatik yönetim |
⚠️ Dikkat: Yeni C++ kodu yazarken neredeyse her zaman
std::stringkullan. 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 >>vegetlineart arda kullanırkencin.ignore()çağırmayı unutma.cin >>satır sonu karakterini (\n) buffer'da bırakır vegetlineonu 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
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
length() / size() | Karakter sayısı | s.length() |
empty() | Boş mu kontrolü | s.empty() |
at(i) / [i] | i. karaktere erişim | s.at(0) |
front() / back() | İlk / son karakter | s.front() |
substr(pos, len) | Alt string | s.substr(0, 5) |
find(str) | Arama (pozisyon döner) | s.find("abc") |
rfind(str) | Sondan arama | s.rfind("abc") |
replace(pos, len, str) | Değiştirme | s.replace(0, 3, "yeni") |
erase(pos, len) | Silme | s.erase(5, 3) |
insert(pos, str) | Ekleme | s.insert(5, "xxx") |
append(str) / += | Sona ekleme | s.append("ek") |
c_str() | C-string'e dönüştür | s.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::nposdö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
AI Asistan
Sorularını yanıtlamaya hazır