C style string in C++

Kerim Fırat
4 min readNov 23, 2020

Bir programlama dilini temel olarak öğrendiğimizde,ilgili dilin veri tipleriyle ilgili temel bilgiyi de edinmiş oluruz. Ancak konu C/Cpp ise durum biraz farklı olabilir. Çünkü C’de kullanılan veri tipi,aynı şekilde Cpp’da kullanmak mümkün olmayabilir.
Bazı meslektaşlar C ile Cpp’yi iki ayrı dil olarak görüyor olsa da,ben buna katılmıyorum. Bana göre ise CCpp,birbirinin devamı ve birbirini tamamlayan teknoloji ve hatta kültürdür.

NOT:Eğer sadece C öğrenecekseniz problem yok. Ancak Cpp öğrenmeye karar verdiğinizde,öncelikle C’yi öğrenmenizi öneririm. Şahsi fikrimdir.

Bu makalede “string” işlemlerini konu alacağız. C kodlarken kullandığımız string işlemlerini Cpp içinde yapamaya çalışacağız ve Cpp’a özel yöntemlerini işleyeceğiz.
C’de kullanılan string işlemleri aynı şekilde Cpp’da da kullanılabilir.
Ancak C stili kullanım Cpp içinde istenmeyen sonuçlara sebep olabilir.
Bu nedenle C stili string işlemlerini Cpp içinde kullanırken farklı yaklaşımlar sergilememiz gerekir. Aşağıda C stili string kullanım örneklerine yer verilmiştir.

NOT: Makalede yer alan tüm örnekler Cpp ortamında işlenmiştir.

C-stili örnek:

using namespace std;
int main(int argc, char** argv) {
char str1[10] = {'M','e','r','h','a','b','a','1' };
char str2[] = "Merhaba2";
const char *str3 = "Merhaba3";
cout << str1 << endl;
cout << str2 << endl;
cout << str3 << endl;

return 0;
}

Yukarıda verilen C stili string işlemlerini yine C stili fonksiyonlarla işleme sokabilirsiniz. Örneğin strcpy(),strlen(),strcat(),strstr(),strcmp(), vb. Bütün bu fonksiyonları aşağıdaki kütüphanelerden birini include ederek kullanabilirsiniz.

#include <cstring>
#include <bits/stdc++.h>

C stili string işlemlerini yukarıdaki şekilde kullanmak gayet normal görünüyor. Ancak sıra dışarıdan veri atamaya gelince istenmeyen durumla karşı karşıya kalıyoruz. Aşağıdaki örneği inceleyelim:

using namespace std;
int main(int argc, char** argv) {
char str1[10] = {'M','e','r','h','a','b','a','1' };
char str2[] = "Merhaba2";
const char *str3 = "Merhaba3";

cin >> str1; //cin ile dışarıdan veri ataması
cin >> str2; // cin ile dışarıdan veri ataması
cout << str1 << endl;
cout << str2 << endl;
cout << str3 << endl;
return 0;
}

Bu örnekte input değeri(tek satırda) “str1e atama yapmak istiyorum” şeklinde girildi.Yani tüm cümleyi str1'e atamak istiyoruz. Ancak aşağıdaki istenmeyen çıktıyı alıyoruz.

Output

Çıktıda(Output) da görüldüğü gibi input cümlemiz str1 ve str2'ye atanmış vaziyette. Yani “std::cin” komutuyla tüm cümleyi str1'e atamak isterken,
aslında boşluklardan itibaren kesip 1.kelimeyi str1'e,2.kelimeyi str2'ye atamış.
Cümlenin geri kalanı kayıp. Şayet bir “cin” daha koymuş olsaydık,sıradaki kelimeyi de ona atayacaktı.

Peki C stili bir string tanımlamak yerine,Cpp’ın bize sağladığı “string” classını kullanırsak durum değişir mi?
Örnek:

using namespace std;
int main(int argc, char** argv) {
char str1[10] = {'M','e','r','h','a','b','a','1' };
char str2[] = "Merhaba2";
const char *str3 = "Merhaba3";

cin >> str1; //cin ile dışarıdan veri ataması
cin >> str2; //cin ile dışarıdan veri ataması

string cppstring; //cpp stili string tanımlama
cin >> cppstring; //cin ile dışarıdan veri ataması

cout << str1 << endl;
cout << str2 << endl;
cout << str3 << endl;
cout << cppstring << endl;
return0;
}

Bu örnekte input değeri(tek satırda) “durum farklı mı olacak?” şeklinde girildiğinde yine aşağıdaki istenmeyen çıktıyı alacağız.

Output

Dolayısıyla string input olarak cümle girdileri için “std::cin” kullanımı uygun değildir. Çünkü “std::cin”,kelimenin sonunda yer alan ilk boşluk karakterinden sonraki girdiyi yok sayacaktır.
İşte bu gibi istenmeyen durumlarla karşılaşmamak için Cpp bize “getline()” fonksiyonu sunuyor. Hatta bu örnekte iki farklı “getline” fonksiyonu kullanacağız. Biri “cin” altında yer alır. Bu fonksiyon yine C stili string tanımlamalarda kullanacağız.
Diğer “getline()” fonksiyonu ise Standart C++ Kütüphanesinde yer alıyor.
Aşağıdaki örnekte her iki kullanıma yer verilmiştir:
Örnek:

using namespace std;
int main(int argc, char** argv) {
char str1[50] = {'M','e','r','h','a','b','a','1' };
char str2[] = "Merhaba2";

/* C stil getline():
* ilk parametre atama yapılacak değişken,ikinci parametre ise maksimum karakter sayısını belirtir.
*/
cin.getline(str1,50);
cin.getline(str2,50);

string cppstring;
//cin.getline(cin,cppstring); //hata!
/* Cpp stil getline():
* ilk parametre istream classının bir nesnesidir ve girdinin nereden okunacağı belirtir.
* ikinci parametre ise atama yapılacak string türü değişkendir.
*/
getline(std::cin,cppstring);

cout << str1 << endl;
cout << str2 << endl;
cout << cppstring << endl;
return 0;
}
Input
Output

Bu örnekte ise C stili string tanımlamaları için “cin.getline()” fonksiyonu,
Cpp stili string için ise “getline()” fonksiyonu kullanıldı.
Bu keyfi bir kullanım değildir ve örnekte de görüldüğü gibi Cpp stili için “cin.getline()” kullanıldığında hata meydana gelmektedir.

Son olarak işleyeceğimiz detay ise C stili string değişkenleri Cpp stili string değişkenlere atamak,ve aynı şekilde Cpp stili string değişkenleri C stili string değişkenlere atamaktır.Aşağıdaki örnekte bu durumlar işlenmiştir.
Örnek:

using namespace std;

int main(int argc, char** argv) {
char str1[50] = {'M','e','r','h','a','b','a','1' };
char str2[] = "Merhaba2";
char *str3 = "Merhaba3";

string s1(str1);//output: Merhaba1
string s2(str2);//output: Merhaba2
string s3(str3);//output: Merhaba3

char *str4 = &(s3[0]);//output: Merhaba3
const char *str5 = s3.c_str();//output: Merhaba3 DİKKAT: const olarak tanımlanmalı!

cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << str4 << endl;
cout << str5 << endl;

return 0;
}

-end of

--

--

Kerim Fırat
Kerim Fırat

Written by Kerim Fırat

Senior Android Platform(AOSP,AAOS) Architect,Open Source Contributor | Turkey Java User Group Vice Chairman | Author

No responses yet