Subject: string'in elemanları harf veya Unicode karakteri değil
D'nin karakter türlerinin Unicode kodlamaları olduğunu biliyoruz. Şu iki sayfada tam olmasa da biraz bilgi var:
http://ddili.org/ders/d/karakterler.html
http://ddili.org/ders/d/dizgiler.html
(Hatta onları yazdığım zaman tam anlamamış olabileceğim için yanlış bilgi bile olabilir!
)
Digital Mars forumunda aynı konu yine açıldı. Sorun, string'in elemanlarına teker teker erişirken görülüyor:
string'in elemanları harf değil, bir kod birimi (code unit); yani harfi UTF-8 kodlamasında oluşturan birimlerin her birisi. Yukarıdaki programın çıktısı, beklendiği gibi, benim Linux konsol ortamında şöyle bozuk oluyor:
Çünkü, string'i oluşturan birimler, yani 'char'lar tek başlarına anlamlı değiller.
Daha ileriye gitmeden önce, kafa karıştıran bir garipliğe dikkat çekmem gerekiyor: Yukarıdaki programda dizgi elemanından sonra yazdırılan boşluk karakterini kaldırın. Yani şu satırı kullanın:
Bu sefer çıktı düzeliyor!
Bu sonuca bakarsak, string'in elemanlarının teker teker kullanılmasında sakınca olmadığını düşünebiliriz. Çünkü sanki teker teker harfleri yazdırmış gibi oluyor. Ama yanlış! Biz aslında yine de teker teker kod birimlerine erişiyoruz.
Düzgün çıkmasının nedeni, benim Linux ortamımın (belki de bütün Linux ortamlarının?) zaten UTF-8 kodlamasıyla çalışmasından kaynaklanıyor. Sonuçta, benim konsola gönderdiğim kod birimleri arka arkaya yine de anlamlı Unicode karakterleri oluşturuyorlar ve o yüzden de çıktı doğru görünüyor.
Aynı programa üç işlev daha ekleyeceğim:
Çıktısı şöyle:
Görüldüğü gibi, yalnızca sonuncusu, yani foreach döngüsünde açıkça dchar isteyeni doğru çalışıyor.
Yani, char'ın Unicode karakteri olamadığını, ama Unicode karakterlerinin UTF-8 kodlamasında kullanılan "kod birimleri" olduklarını hatırlayalım.
Ali
http://ddili.org/ders/d/karakterler.html
http://ddili.org/ders/d/dizgiler.html
(Hatta onları yazdığım zaman tam anlamamış olabileceğim için yanlış bilgi bile olabilir!
)Digital Mars forumunda aynı konu yine açıldı. Sorun, string'in elemanlarına teker teker erişirken görülüyor:
import std.stdio; void harfler_indeks_ile(const char[] dizgi) { for (int i = 0; i != dizgi.length; ++i) { write(dizgi[i], ' '); } writeln(); } void main() { string dizgi = "abcçdefgğhıijklmnoöpqrsştuüvwxyz"; harfler_indeks_ile(dizgi); }
string'in elemanları harf değil, bir kod birimi (code unit); yani harfi UTF-8 kodlamasında oluşturan birimlerin her birisi. Yukarıdaki programın çıktısı, beklendiği gibi, benim Linux konsol ortamında şöyle bozuk oluyor:
a b c � � d e f g � � h � � i j k l m n o � � p q r s � � t u � � v w x y z
Çünkü, string'i oluşturan birimler, yani 'char'lar tek başlarına anlamlı değiller.
Daha ileriye gitmeden önce, kafa karıştıran bir garipliğe dikkat çekmem gerekiyor: Yukarıdaki programda dizgi elemanından sonra yazdırılan boşluk karakterini kaldırın. Yani şu satırı kullanın:
write(dizgi[i]);
Bu sefer çıktı düzeliyor!
abcçdefgğhıijklmnoöpqrsştuüvwxyz
Bu sonuca bakarsak, string'in elemanlarının teker teker kullanılmasında sakınca olmadığını düşünebiliriz. Çünkü sanki teker teker harfleri yazdırmış gibi oluyor. Ama yanlış! Biz aslında yine de teker teker kod birimlerine erişiyoruz.
Düzgün çıkmasının nedeni, benim Linux ortamımın (belki de bütün Linux ortamlarının?) zaten UTF-8 kodlamasıyla çalışmasından kaynaklanıyor. Sonuçta, benim konsola gönderdiğim kod birimleri arka arkaya yine de anlamlı Unicode karakterleri oluşturuyorlar ve o yüzden de çıktı doğru görünüyor.
Aynı programa üç işlev daha ekleyeceğim:
import std.stdio; void harfler_indeks_ile(const char[] dizgi) { for (int i = 0; i != dizgi.length; ++i) { write(dizgi[i], ' '); } writeln(); } void harfler_foreach_tür_belirtmeden(const char[] dizgi) { foreach (harf; dizgi) { write(harf, ' '); } writeln(); } void harfler_foreach_char_ile(const char[] dizgi) { foreach (char harf; dizgi) { write(harf, ' '); } writeln(); } void harfler_foreach_dchar_ile(const char[] dizgi) { foreach (dchar harf; dizgi) { write(harf, ' '); } writeln(); } void main() { string dizgi = "abcçdefgğhıijklmnoöpqrsştuüvwxyz"; harfler_indeks_ile(dizgi); harfler_foreach_tür_belirtmeden(dizgi); harfler_foreach_char_ile(dizgi); harfler_foreach_dchar_ile(dizgi); }
Çıktısı şöyle:
a b c � � d e f g � � h � � i j k l m n o � � p q r s � � t u � � v w x y z
a b c � � d e f g � � h � � i j k l m n o � � p q r s � � t u � � v w x y z
a b c � � d e f g � � h � � i j k l m n o � � p q r s � � t u � � v w x y z
a b c ç d e f g ğ h ı i j k l m n o ö p q r s ş t u ü v w x y z
Görüldüğü gibi, yalnızca sonuncusu, yani foreach döngüsünde açıkça dchar isteyeni doğru çalışıyor.
Yani, char'ın Unicode karakteri olamadığını, ama Unicode karakterlerinin UTF-8 kodlamasında kullanılan "kod birimleri" olduklarını hatırlayalım.

Ali
acehreli
Show profile
Link to this post