Standart C Programlama Dili


8.2. Geniş Karakterler Ve Çokbaytlı Karakterler

Aslında, tam olarak tek bayt anlamına gelen char tipinin 256 farklı değer alabilmesi temin edilmiştir. Japonca veya Çince gibi, bazı diller 256’dan fazla simge gerektirmektedir. Böyle dillerle çalışabilmek için, geniş karakterler ve çokbaytlı karakterler kavramı geliştirilmiştir.

Geniş Karakterler

Bir geniş karakter wchar_t adlı standart tipe aittir. Bu tamsayı tipi herhangi bir karakter takımındaki bütün değerleri gösterebilecek kadar büyük olan, normalde 16 veya 32 bitlik bir tiptir. (Daha yeni standartlarda bu ayırımı netleştirmek için char16_t ve char32_t tipleri de eklenmiştir.) Başlangıçtaki "’ın hemen önüne bir L, u veya U harfi konarak, sırasıyla wchar_t, char16_t veya char32_t tiplerinden oluşan geniş karakter dizileri tanımlanabilir. Karakter değişmezleri için de, benzer şekilde, '’ın önüne L, u veya U harfi konulur.

wchar_t gkd[] = L"Bir genis karakter dizisi";
wchar_t gk = L'h';

Tek bayt karakterler için kullanılan karakter dizisi işleme fonksiyonlarının geniş karakterler için kullanılan karşılıkları bulunmaktadır. Genelde wchar.h başlık dosyasında tanımlanmış olan bu fonksiyonlardan bazıları aşağıda listelenmiştir (bildiğimiz tek bayt karakter fonksiyon karşılıkları parantez içinde verilmiştir):

wcslen karakter dizisinin uzunluğu (strlen),

wcscpy karakter dizisi kopyalama (strcpy),

wcscmp karakter dizisi karşılaştırma (strcmp),

wcschr karakter dizisinde ilk karakteri bulma (strchr),

wcsrchr karakter dizisinde son karakteri bulma (strrchr),

Örneğin, wchar_t * gkd = L"kırk ağaç" şeklinde tanımlanmış bir geniş karakter dizisinin uzunluğunu (bu örnekte 9) bulmak için wcslen(gkd) fonksiyonunu kullanmamız gerekir.

Bir geniş karakter dizisini okumak veya yazmak için %ls dönüşüm tanımlamasını kullanmak gerekir. Tek bir geniş karakter için de %lc kullanılır.

Çokbaytlı Karakterler

Bir çokbaytlı karakter, çevresel bir aygıta yazılabilecek, bir veya birden fazla bayttan oluşan, sıradan bir karakter sırasıdır. Tüm çokbaytlı karakterler aynı sayıda bayt tutmazlar; herhangi bir çokbaytlı karakterin uzunluğu bir ile dört bayt arasında değişir. Tek bir adet çokbaytlı karakterin uzunluğunu (kaç bayt tuttuğunu) elde etmek için mblen fonksiyonu kullanılır. Bir çokbaytlı karakteri veya karakter dizisini tanımlamak için '’ ve "’ın hemen önüne u8 yazılabilir.

Örneğin, char * cbkd = u8"kırk ağaç" şeklinde tanımlanmış bir çokbaytlı karakter dizisinin karakter sayısını (bu örnekte 9) hesaplamak kolay değildir. strlen(cbkd) fonksiyonu 12 değerini döndürecektir. Bunun nedeni, bu dizi içinde her biri tek bayt tutan 6 karakter (krk aa) ve her biri ikişer bayt tutan 3 Türkçe karakter (ığç) olmasıdır. Gerçek karakterlerin sayısını hesaplamak için kullanılacak bir yöntem daha aşağıda anlatılan dönüştürme fonksiyonlarından mbstowcs’i kullanarak çokbaytlı karakter dizisini geniş karakter dizine çevirip, sonra da geniş karakter dizisinin uzunluğunu wcslen ile hesaplamak olabilir:

char * cbkd = u8"kırk ağaç";
wchar_t gkd[100];
mbstowcs(gkd,cbkd,100);
uzunluk = wcslen(gkd);

Diğer bir yöntem de aşağıdakidir:

size_t uzunluk;
char * g = cbkd;
char * son = g + strlen(g);
mblen(NULL, 0); /* dönüşüm durumunu sıfırla */
for (uzunluk = 0; g < son; uzunluk++) {
  int n = mblen(g, son - g);    /* bulunduğumuz karakter kaç bayt? */
  if (n == -1)  /* hata */
    break;
  g += n;
}

Yukarıda anlatılan iki karakter türü birbirleriyle yakın ilişkili oldukları için, bunlar arasında dönüştürme yapmayı isteriz. Aşağıdaki fonksiyonlar bu işi yaparlar:

wctomb bir geniş karakteri bir çokbaytlı karaktere,

mbtowc bir çokbaytlı karakteri bir geniş karaktere,

wcstombs bir geniş karakter dizisini bir çokbaytlı karakter dizisine,

mbstowcs bir çokbaytlı karakter dizisini bir geniş karakter dizisine dönüştürür.