Selam,
Bugün diziler konusuna devam ediyorum. Bu sefer “karakter dizisi“ni öğrenmeye çalışacağım. Dizgi, katar ya da string olarakta adlanırılabiliyor. Aslında string
modern programlama dillerine ait bir terim. Metinsel verileri saklamak için kullanılan değişken türünü ifade ediyor ama C dilinde string
veri tipi yok. Bunun yerine karakterleri (char
) bir araya getirerek bir dizi oluşturuyoruz. Yine de ben karakter dizisi
yerine string
terimini kullanacağım.
Stringlere İlk Bakış
Önce basitçe bir karakter dizisi tanımlamakla başlıyorum. Dizilerde geçerli olan kurallar stringler içinde geçerli.
char karakterDizisi[] = {'S','E','L','A','M'};
Bir dizi tanımlandığı zaman bellekte ardışık olarak yer ayrılıyordu. karakterDizisi
nin indislerine göre adreslerini yazdıralım:
int i; for(i=0;i<5;i++) { printf("%u ", &karakterDizisi[i]); }
Çıktı:
2337488 2337489 2337490 2337491 2337492
Görüldüğü üzere adresler birer birer artıyor. İlk derslerde öğrendiğim hangi veri tipinin bellekte ne kadar yer kapladığı meselesi şimdi daha da netleşti.
String tanımlamanın başka bir yolu ise çift tırnakları (” “) kullanmak. Bu şekilde metni bir bütün olarak yazabiliriz.
char baskaKarakterDizisi[] = "Hırs, hasaret ve muvaffakiyetsizliğin sebebidir.";
Çift tırnaklar içinde bazı özel karakterleri kullanmak istediğimde, kaçış karakterini kullanmam gerektiğini de öğrenmiştim. Yani \ karakterini.
char string[] = "\"İslamiyetin menşei, ilim; esası, akıldır.\"";
Stringler konusunda önemli bir nokta ise, her zaman “null
” karakteri ile sonlandıkları. Yani “\0
” karakteri ile. \0
ASCII tablosundaki değeri 0 dır.
Stringler de bir dizi olduğuna göre tek tek elemanlarına erişebiliriz demektir.
char film[10] = "Matrix";
Yukarıdaki dizi için,
film[0]: M film[1]: a film[2]: t film[3]: r film[4]: i film[5]: x film[6]: '\0'
demektir. Şimdi bunu bir do-while
döngüsüyle görelim. Döngü ‘\0
‘ karakterini görene kadar devam etsin. Bakalım ne kadar dönecek?
int i=0; do { printf("film[%d]: %c \n", i, film[i]); i++; }while(film[i] != '\0');
Çıktı:
film[0]: M film[1]: a film[2]: t film[3]: r film[4]: i film[5]: x
Bir string
in boyutunu gereğinden az verirsek C bize hata vermez ama fazla olan veriler saklanmaz.
char film[3] = "Matrix";
Bu string
i ekrana yazdırıyorum. Bu arada puts()
diğer kullanım şeklini de öğrenmiş oluyorum.
puts(film);
Çıktı:
Mat
Stringlere İlk Değer Ataması
Buraya kadar olan kısımda zaten bunları yaptım ama hızlıca tekrar değineceğim. Karakter dizilerine şu şekillerde ilk atamlar yapılabilir:
- Dizinin boyutunu belirtmeden karakterleri yazarak
- Metinsel ifadeyi direkt yazarak
Pointer
kullanarak (pointer
kavramını henüz öğrenmedim)
1-Boyut Belirtilmemiş Diziler ve Karakterler
Bir diziye boyutunu belirlemeden elemanları girdiğim zaman benim için elemanları sayıp boyutunu otomatik hesaplıyordu. Aynı durum karakter dizileri için de geçerli. Elemanları yine { } içine yazıyorum ama bu kez her bir elemanı ‘ ‘ içinde belirtiyorum. Ve dizinin sonuna ulaştığımı bildirmek için null
karakterini yani '\0'
eklemeyi unutmamak gerek.
char name [] = {'Y', 'U', 'S', 'U', 'F', '\0'};
2-Metinsel İfadeyi Direkt Girerek
En pratik ilk değer ataması bu şekilde oluyor. ” ” arasına metinsel ifadeyi giriyoruz. Üstelik bu yöntemle sonlandırı karakteri yani ‘\0
‘ elle girmeme gerek kalmıyor çünkü benim için derleyici bunu yapıyor.
3-Pointer Kullanarak
Pointer
kavramını henüz öğrenmediğim için bunu şimdi atlıyorum ama isteyenler olursa buraya linki bırakıyorum.
Stringler için Giriş İşlemleri
3 tane fonksiyon kullanabiliriz
getchar()
gets()
scanf()
getchar()
getchar()
fonksiyonu enter girilene kadar klavyeden veri almaya devam eder ama sadece ilk girilen karakteri saklar. Eğer bir string saklamak istersek şu şekilde kullanabiliriz.
int i = 0; char name[20]; puts("Lütfen isminizi girin:"); while((name[i] = getchar())!='\n') i++ ; puts(name);
Yukarıdaki kod enter girilene kadar girilen karakterleri name
içine atıyor. Bu sırada her karakter girişinde i
değeri 1 artarak dizinin indisi ilerletiliyor. Son olarak entera basıldıktan sonra ekrana girilen değeri yazdırıyor.
gets()
gets()
fonksiyonu da enter girilene kadar boşluklar da dahil olmak üzere girilen karakterleri saklar ve dizinin sonuna otomatik olarak ‘\0
‘ karakterini de ekler.
Aşağıda gets() fonksiyonun kullanım şeklini görüyoruz:
char name[20]; puts("Lütfen isminizi girin:"); gets(name);
gets()
ile stringleri almak pratik gözükse de kötü bir yanı var. Yukarıda name[20]
için 20 karakterlik bir alan belirlenmiş olsa da gets() bunu dikkate almaz. 30 karakter girilse de bunu saklamaya çalışır. Bu durumda “overflow” yaşanabilir ve program çökebilir.
scanf()
Bu fonksiyonu daha önce birçok kez kullanmıştım zaten. Şimdi de string ifadeler için kullanım şekline bakalım:
char name[20]; puts("Lütfen isminizi girin:"); scanf("%s",name);
İlk dikkat ettiğim nokta stringler için placeholer %s
. Diğer nokta ise &
operatörü kullanılmamış.
scanf()
, gets()
ve getchar()
dan farklı olarak, entera kadar olan tüm karakterleri değil boşluğa kadar olan karakterleri kabul ediyor. Yani yukarıdaki kod için name
değişkenine “Yusuf Karaçin” yazarsam sadece “Yusuf” saklanır.
scanf()
fonksiyonu ile boşlukları da saklamak istersek şu kodu kullanabiliriz:
scanf("%[^\n]s",name);
Yalnız scanf()
fonksiyonu da overflow a açıktır. Overflowlarla baş etmeyi ilerledikçe öğrenmeyi umut ediyorum. Ayrıca stringleri alırken neden & kullanmadığımıza gelirsek bu da pointerlarla alakalı bir konu olduğu için şimdilik atlıyorum.
Stringleri Yazdırma
Yukarıda örnekleri gördüm ama yine hızlıca değinmek istiyorum:
putchar()
puts()
printf()
putchar()
Adından anlaşıldığı üzere tek bir karakter yazdırmak için kullanılıyor. 3 farklı şekilde kullanabiliriz:
char a = 'Y'; char isim[] = "Yusuf"; putchar('a'); // a yazar putchar(a); // a değişkeni içindeki değeri yazar. Yani Y putchar(isim[1]); //isim dizisinin 1. indisini yazar. Yani u
puts()
Kullanıcıya bildirmek vermek istediğim zaman sıklıkla tercih ettiğim fonksiyon. Kullanım şekillerini hızlıca hatırlayalım:
char isim[] = "Yusuf"; puts(isim); //isim değişkenini, yani Yusuf yazar puts("Hoşgeldiniz!"); // hoşgeldiniz! yazar
printf()
İlk konularda uzunca incelemiştim. Şimdi de stringler için kısaca göz atıyorum:
char isim[] = "Yusuf"; char x = 'a'; printf("Merhaba, %s", isim); //Merhaba, Yusuf yazar printf("\n Hoşgeldiniz!"); // bir sayır aşağıya iner ve hoşgeldiniz! yazar printf("%d",x); // 97 yazar
Stringler için placeholderın %s
olduğunu bir kez daha görmüş oldum.
Stringleri Integer a Çevirme (atoi)
Bazen metinsel bir ifade aslında sayısal bir değer taşıyor olabilir. Mesela kullanıcıdan string olarak “17” değerini aldık. Bunun üzerinde matematiksel işlemler yapmak istersek öncelikle sayısal veri tipine çevirmemiz gerekir. Bunun için de atoi()
fonksiyonunu kullanıyoruz.
atoi = A to I =Alphabet to Integer
int num; num = atoi("98"); printf("\nNum: %d",num);
ya da
int num; char marks[3] = "98"; num = atoi(marks); printf("\nNum : %d",num);
şeklinde kullanabiliriz.
Özet
- Modern dillerideki
string
C dilindekarakter dizisi
dir. - Diziler için geçerli olan kurallar, karakter dizileri için de geçerli.
- Karakter dizilerinin sonunda, bitirici karakter ‘\0’ olmalı.
- İlk değer atamaları çift tırnak içinde direkt metinsel ifade şeklinde ya da tek tek karakter şeklinde olabilir.
- Tek tek karakter girilirse, bitirici karakter olarak ‘\0’ eklenmeli.
putchar()
tek bir karakter yazdırır,getchar()
tek bir karakter alır.- Stringi sayısal ifadeye çevirmek için
atoi()
fonksiyonu kullanılabilir.
Yorumlar