Forum: Ders Arası RSS
"Dizgiler" 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ı: "Dizgiler" dersine ek (taslak)
Bu bölümü de Dizgiler dersine ekliyorum:

readf yerine readln ve chomp

Konsoldan satır okumak programcılıkta yaygın bir işlem değildir. Yine de deneme programlarında kullanılacağı için girişten satır okuma ile ilgili bazı karışıklıklara burada değinmek istiyorum.

Dizgiler bütün karakterleri barındırabildikleri için satır sonu anlamına gelen '\n' karakterini de okuyabilirler. O yüzden, girdiğimiz bilgilerin sonunda bastığımız Enter tuşu da '\n' değeri ile okunur ve dizginin parçası haline gelir.

Bunun sonucunda da şimdiye kadar gördüklerimiz gibi readf ile yazılmış olan şu program istediğimiz gibi işlemez:

import std.stdio;
 
void main()
{
    char[] isim;
 
    write("İsminiz nedir? ");
    readf(" %s", &isim);
 
    writeln("Çok memnun oldum ", isim, "!");
}

Programa verilen isimden sonra basılan Enter girişi sonlandırmaz:

İsminiz nedir? Ali
                    ← Enter'a basıldığı halde giriş sonlanmaz
                    ← (bir kere daha basıldığını varsayalım)


Dahası, girişten kaç karakter okunmak istendiği de bilinmediği için readf giriş tükenene kadar gelen bütün karakterleri dizginin içine okur.

Konsolda girişi sonlandırmak için Linux ortamlarında Ctrl-D'ye, Windows ortamlarında da Ctrl-Z'ye basılır. Öyle yaptığınızda, Enter'lar nedeniyle oluşan satır sonu karakterlerinin de dizginin parçası haline geldiklerini görürsünüz:

Çok memnun oldum Ali
                    ← isimden sonra "satır sonu" var
!                   ← (bir tane daha)


Bu yüzden readf çoğu durumda girişten dizgi okumaya uygun değildir. Onun yerine ismi "satır oku" anlamındaki "read line"dan türemiş olan readln işlevidir.

readln'ın kullanımı readf'ten farklıdır. " %s" düzen dizgisini ve & işlecini gerektirmez:

import std.stdio;
 
void main()
{
    char[] isim;
 
    write("İsminiz nedir? ");
    readln(isim);
 
    writeln("Çok memnun oldum ", isim, "!");
}

Buna rağmen satır sonunu belirleyen kodu o da barındırır:

İsminiz nedir? Ali
Çok memnun oldum Ali
!                   ← isimden sonra yine "satır sonu" var


Dizgilerin sonundaki satır sonu kodları std.string modülündeki chomp ile silinebilir:

import std.stdio;
import std.string;
 
void main()
{
    char[] isim;
 
    write("İsminiz nedir? ");
    readln(isim);
    isim = chomp(isim);
 
    writeln("Çok memnun oldum ", isim, "!");
}

Yukarıdaki chomp ifadesi isim'in sonundaki satır sonu kodlarının silinmiş halini döndürür. O halinin tekrar isim'e atanması da isim'i değiştirmiş olur:

İsminiz nedir? Ali
Çok memnun oldum Ali!    ← "satır sonu" kodlarından arınmış olarak


readln ve chomp zincirleme olarak daha kısa da yazılabilir:

    string isim = chomp(readln());

O yazımı string türünü tanıttıktan sonra kullanmaya başlayacağım.

Ali
erdem (Moderatör) #2
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Burada dchar [] ya da wchar [] kullanmamanızın nedenini bahsettiğiniz hata kaydı nedeniyle hiç sormuyorum :)

Ama normalde Türkçe karakter kullanan her programda wchar[] ya da dchar [] kullanmayı tercih ederiz değil mi. Hatta japonlar gibi 4 bayt yer tutan karakterlerimiz olmadığı için wchar[] yeterli olur sanırım.

Gene burada readln'i aynı zamanda dchar[] ve wchar[] alacak şekilde tasarlamış olmalarını tercih ederdim.

Gayet güzel anlatmışsınız. Teşekkürler! :)
acehreli (Moderatör) #3
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ı
erdem:
Burada dchar [] ya da wchar [] kullanmamanızın nedenini bahsettiğiniz hata kaydı nedeniyle hiç sormuyorum :)

Taslağın baş tarafının açık olmadığını farkedip biraz düzeltmiştim bile. Aslında hayır: girişten herhangi tür bir dizgi almamamın nedeni, dizgilerin girişin sonuna kadar okuyor olmaları. (Eğer bu davranış da hata değilse tabii.)

Bana mantıklı geliyor: "girişten dizgi al" deyince nerede durulması gerektiğini söylemezsek bütün giriş alınır.

Ve aslında readf(&bir_dinamik_dizgi) doğru olarak işliyor ve bütün girişi okuyor.

Biz ise bir satır bilgi istediğimiz için readln kullanmalıyız. Bilgi kaybı olmasın diye satır sonu kodlarını atmamış olmalarını da anlıyoruz ve zaten chomp() ile kesip atmak kolay.

Ama normalde Türkçe karakter kullanan her programda wchar[] ya da dchar [] kullanmayı tercih ederiz değil mi. Hatta japonlar gibi 4 bayt yer tutan karakterlerimiz olmadığı için wchar[] yeterli olur sanırım.

Aslında bütün karakterler için bile char[] kullanabiliyoruz, değil mi... Çünkü UTF-8 kodlaması anlamına gelir ve bütün Unicode'u destekler.

Aklımızda tutmamız gereken, char[]'ın ve wchar[]'ın elemanlarının bildiğimiz anlamda harf veya karakter olmadıkları. Özel durumlarda o da oluyor ama: char[]'ın elemanları ASCII metinlerde karakter kabul ediliyor, whar[]'da özellikle 2 ve daha az baytla kodlanan karakterlerde. Ama bunlar riskli beklentiler.

Elemanlarını tek tek harf olarak kullanabildiğimiz tür dchar[]. Yapmak istediğimiz işe göre seçmeliyiz. Sanırım özel bir nedeni yoksa, örneğin çok büyük dizgilerle ilgilenmiyorsak her zaman için dchar[] kullanabiliriz.

(Bütün bunlar string, wstring, ve dstring için de geçerli tabii ki.)

Gene burada readln'i aynı zamanda dchar[] ve wchar[] alacak şekilde tasarlamış olmalarını tercih ederdim.

Duyduğum kadarıyla hepsi olacak. Yavaş yavaş hallediyorlar.

Yaptıkları başka bir şey, std.string'deki bazı algoritmaları std.algorithm ve std.array'e taşımak oldu. Onları şablon da yaptıkları için o algoritmalar her türle işleyebiliyor. Şurada "IMPORTANT NOTE" altında:

  http://digitalmars.com/d/2.0/phobos/std_string.html

Sonuçta bizim std.string wiki sayfamız da iyice yanlış bilgi vermeye başladı:

  http://ddili.org/wiki/index.php?title=Std.string

Ali
erdem (Moderatör) #4
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
Aslında bütün karakterler için bile char[] kullanabiliyoruz, değil mi... Çünkü UTF-8 kodlaması anlamına gelir ve bütün Unicode'u destekler.

Aklımızda tutmamız gereken, char[]'ın ve wchar[]'ın elemanlarının bildiğimiz anlamda harf veya karakter olmadıkları.

Hımm. Ben bunu bilmiyordum öğrendiğim iyi oldu. Teşekkürler! :)
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-22, 06:51:11 (UTC -08:00)