Forum: Ders Arası RSS
"Karakterler" dersine ek (taslak)
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: "Karakterler" dersine ek (taslak)
D'nin Unicode desteğini daha iyi anlamış birisi olarak o derse bazı ekler yapıyorum.

Sanırım bu bölümü kaldıracağım, çünkü açıklamasını vermeye çalıştığım davranışın bir Phobos hatası olduğunu anladım:

Girişten karakter okumadaki sorunlar

D'nin Unicode konusunda getirdiği güç ve esneklik, girişten karakter okurken beklenmedik sonuçlar doğurabilir. Bu çelişki, karakter ile ne kastedildiğinin açık olmaması nedeniyledir. Daha ileriye gitmeden önce, bu sorunu yaşayan bir program göstermek istiyorum.

import std.stdio;
 
void main()
{
    char harf;
    write("Lütfen bir harf girin: ");
    readf(" %s", &harf);
    writeln("Okuduğum harf: ", harf);
}

Yukarıdaki programı Unicode kodlaması kullanılmayan bir ortamda, örneğin bir Windows işletim sistemi konsolunda çalıştırırsanız, programın girişinden aldığı Türkçe harfleri doğru olarak yazdırdığını görürsünüz.

Öte yandan aynı programı çoğu Linux konsol penceresinde olduğu gibi bir Unicode ortamında çalıştırırsanız, yazdırılan harfin sizin yazdığınızla aynı olmadığını görürsünüz. Örneğin UTF-8 kodlaması kullanan bir konsolda ASCII tablosunda bulunmayan bir harf girildiğinde:

Lütfen bir harf girin: ğ
Okuduğum harf:           ← girilen harf görünmüyor


Bunun nedeni, UTF-8 kodlaması kullanan konsolun ASCII tablosunda bulunmayan ğ gibi harfleri birden fazla kod ile temsil etmesi, ve readf'in char okurken bu kodlardan yalnızca ilkini alıyor olmasıdır. O char asıl karakteri temsil etmeye yetmediği için de writeln'ın yazdırdığı eksik kodlanmış olan harf konsolda gösterilememektedir.

char okurken kodlamayı oluşturan kodların okunduklarını harfi iki farklı char olarak okuyarak görebiliriz:

import std.stdio;
 
void main()
{
    char birinci_kod;
    char ikinci_kod;
    write("Lütfen bir harf girin: ");
    readf(" %s", &birinci_kod);
    readf(" %s", &ikinci_kod);
    writeln("Okuduğum harf: ", birinci_kod, ikinci_kod);
}

Program girişten iki char okumakta ve onları aynı sırada çıkışa yazdırmaktadır. O char değerlerinin art arda konsola gönderilmiş olmaları, bu sefer harfin UTF-8 kodlamasını standart çıkış tarafında tamamlamakta ve karakter doğru olarak gösterilmektedir:

Lütfen bir harf girin: ğ
Okuduğum harf: ğ         ← iki char'ın oluşturmuş olduğu harf


Bu sonuçlar standart giriş ve çıkışın char akımları olmalarından kaynaklanır. Karakterlerin iki ders sonra göreceğimiz dizgiler aracılığıyla aslında çok daha rahat okunduklarını göreceksiniz.

Ama aşağıdaki bölüm doğru:

D'nin Unicode desteği

Unicode çok büyük ve karmaşık bir standarttır. D, Unicode'un tamamını değil ama oldukça kullanışlı bir alt kümesini destekler.

Unicode ile kodlanmış bir metin en aşağıdan en yukarıya doğru şu düzeylerden oluşur:

    * kod birimi (code unit): UTF kodlamalarını oluşturan kod değerleridir. Unicode karakterleri, kodlamaya ve karakterin kendisine bağlı olarak bir veya daha fazla kod biriminden oluşabilirler. Örneğin UTF-8 kodlamasında a karakteri tek kod biriminden, ğ karakteri ise iki kod biriminden oluşur.

      D'nin char, wchar, ve dchar türleri sırasıyla UTF-8, UTF-16, ve UTF-32 kod birimlerini ifade ederler.


    * kod noktası (code point): Unicode'un tanımlamış olduğu her harf, im, vs. bir kod noktasıdır. Örneğin a ve ğ iki farklı kod noktasıdır.

      Bu kod noktaları kodlamaya bağlı olarak bir veya daha fazla kod birimi ile ifade edilirler. Yukarıda da değindiğim gibi, UTF-8 kodlamasında a tek kod birimi ile, ğ ise iki kod birimi ile ifade edilir. Öte yandan, her ikisi de UTF-16 ve UTF-32 kodlamalarında tek kod birimi ile ifade edilirler.

      D'de kod noktalarını tam olarak destekleyen tür dchar'dır. char ve wchar ise yalnızca kod birimi türü olarak kullanılmaya elverişlidirler.

    * karakter (character): yazı sistemlerinde kullanılmak üzere Unicode'un tanımlamış olduğu bütün şekiller, imler, ve konuşma dilinde "karakter" dediğimiz her şey bu tanıma girer.

      Bu konuda Unicode'un getirdiği bir karışıklık, bazı karakterlerin birden fazla kod noktasından oluşabilmeleridir. Örneğin ğ harfini ifade etmenin iki yolu vardır:

          o tek başına ğ kod noktası olarak

          o art arda gelen g ve  ̆ kod noktaları olarak (g ve sonrasında gelen birleştirici (combining) breve şapkası)

      D, kod noktalarının bileşimlerinden oluşan karakter kavramını desteklemez. D'nin gözünde tek kod noktası olan ğ ile art arda gelen g ve  ̆ karakterlerinin ilgileri yoktur.

Özet

    * Unicode, dünya yazı sistemlerindeki bütün karakterleri destekler
    * char UTF-8 kodlaması içindir; karakterleri ifade etmeye genelde elverişli olmasa da ASCII tablosunu destekler
    * wchar UTF-16 kodlaması içindir; karakterleri ifade etmeye genelde elverişli olmasa da özel durumlarda birden fazla alfabe karakterini destekler
    * dchar UTF-32 kodlaması içindir; 32 bit olması nedeniyle bütün Unicode karakterlerini destekler ve kod noktası olarak kullanılabilir

Ali
erdem (Moderatör) #2
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
Bunun nedeni, UTF-8 kodlaması kullanan konsolun ASCII tablosunda bulunmayan ğ gibi harfleri birden fazla kod ile temsil etmesi, ve readf'in char okurken bu kodlardan yalnızca ilkini alıyor olmasıdır. O char asıl karakteri temsil etmeye yetmediği için de writeln'ın yazdırdığı eksik kodlanmış olan harf konsolda gösterilememektedir.

char okurken kodlamayı oluşturan kodların okunduklarını harfi iki farklı char olarak okuyarak görebiliriz:

import std.stdio;
 
void main()
{
    char birinci_kod;
    char ikinci_kod;
    write("Lütfen bir harf girin: ");
    readf(" %s", &birinci_kod);
    readf(" %s", &ikinci_kod);
    writeln("Okuduğum harf: ", birinci_kod, ikinci_kod);
}

Program girişten iki char okumakta ve onları aynı sırada çıkışa yazdırmaktadır. O char değerlerinin art arda konsola gönderilmiş olmaları, bu sefer harfin UTF-8 kodlamasını standart çıkış tarafında tamamlamakta ve karakter doğru olarak gösterilmektedir:


dchar kullanınca da gene bahsettiğiniz hata kaydına çıkıyor  ;-)

Bu arada Unicode ile ilgili güzel ayrıntılar vermişsiniz.
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 00:17:30 (UTC -08:00)