D Programlama Dili – Programlama dersleri ve D referansı
Ali Çehreli

gösterge: [pointer], bir değişkeni gösteren değişken
standart çıkış: [standard output], program çıktısının normalde gönderildiği akım
... bütün sözlük



İngilizce Kaynaklar


Diğer




Girişten Bilgi Almak

Girilen bilginin daha sonradan kullanılabilmesi için bir değişkende saklanması gerekir. Örneğin okulda kaç tane öğrenci bulunduğu bilgisini alan bir program, bu bilgiyi int türünde bir değişkende tutabilir.

Yazdırma işlemi sırasında dolaylı olarak stdout akımının kullanıldığını bir önceki bölümde gördük. Bu, bilginin nereye gideceğini açıklamaya yetiyordu; çünkü stdout, standart çıkış demektir. Çıkışa ne yazdırılacağını da parametre olarak veriyorduk. Örneğin write(öğrenci_sayısı); yazmak, çıkışa öğrenci_sayısı değişkeninin değerinin yazdırılacağını söylemeye yetiyordu. Özetlersek:

akım:       stdout
işlem:      write
yazdırılan: öğrenci_sayısı değişkeninin değeri
hedef:      normalde ekran

write'ın karşılığı readf'tir. İsmindeki "f", "belirli bir düzende"nin İngilizcesi olan "formatted"dan gelir.

Standart girişin de stdin olduğunu görmüştük.

Okuma durumunda bundan başkaca önemli bir ayrıntı vardır: okunan bilginin nerede depolanacağının da belirtilmesi gerekir. Okuma işlemini de özetlersek:

akım:       stdin
işlem:      readf
okunan:     bir bilgi
hedef:      ?

Bilginin depolanacağı hedef belirtilirken bir değişkenin adresi kullanılır. Bir değişkenin adresi, o değişkenin değerinin bellekte yazılı olduğu yerdir.

D'de isimlerden önce kullanılan & karakteri, o isimle belirtilen şeyin adresi anlamına gelir. readf'e okuduğu bilgiyi yerleştireceği yer bu şekilde bildirilir: &öğrenci_sayısı. Burada &öğrenci_sayısı, "öğrenci_sayısı değişkenine" diye okunabilir. Bu kullanım, yukarıdaki soru işaretini ortadan kaldırır:

akım:       stdin
işlem:      readf
okunan:     bir bilgi
hedef:      öğrenci_sayısı değişkeninin bellekteki yeri

İsimlerin başına & karakteri koymak o ismin belirttiği şeyin gösterilmesi anlamına gelir. Bu gösterme kavramı, sonraki bölümlerde karşılaşacağımız referansların ve göstergelerin de özünü oluşturur.

readf konusunda bir noktayı ilerideki bölümlere bırakacağız ve şimdilik ilk parametresi olarak "%s" kullanmak gerektiğini kabul edeceğiz:

    readf("%s", &öğrenci_sayısı);

(Not: Çoğu durumda aslında boşluk karakteri ile " %s" yazmak gerekeceğini aşağıda gösteriyorum.)

readf aslında & karakteri olmadan da kullanılabilir:

    readf("%s", öğrenci_sayısı);    // öncekinin eşdeğeri

Her ne kadar & kullanılmadığında kod daha okunaklı ve güvenli olsa da, sizi hem referans kavramına hem de parametrelerin referans olarak geçirilmeleri kavramına alıştırmış olmak için readf'i bu kitapta göstergelerle kullanmaya devam edeceğim.

"%s", verinin değişkene uygun olan düzende dönüştürüleceğini belirtir. Örneğin girişten gelen '4' ve '2' karakterleri, bir int'e okunduklarında 42 tamsayı değerini oluşturacak şekilde okunurlar.

Bu anlatılanları gösteren programda önce sizden öğrenci sayısını bildirmeniz isteniyor. İstediğiniz değeri yazdıktan sonra Enter'a basmanız gerekir.

import std.stdio;

void main() {
    write("Okulda kaç öğrenci var? ");

    // Öğrenci sayısının tutulacağı değişkenin tanımlanması
    int öğrenci_sayısı;

    /* Girişten gelen bilginin öğrenci_sayısı değişkenine
     * atanması */
    readf("%s", &öğrenci_sayısı);

    writeln(
      "Anladım: okulda ", öğrenci_sayısı, " öğrenci varmış.");
}
Boşlukların gözardı edilmelerinin gerekmesi

Yukarıdaki gibi programlarda değerleri yazdıktan sonra Enter tuşuna basılması gerektiğini biliyorsunuz. Kullanıcının Enter tuşuna basmış olması da özel bir kod olarak ifade edilir ve o bile programın standart girişinde belirir. Programlar böylece bilgilerin tek satır olarak mı yoksa farklı satırlarda mı girildiklerini algılayabilirler.

Bazı durumlarda ise girişte bekleyen o özel kodların hiçbir önemi yoktur; süzülüp gözardı edilmeleri gerekir. Yoksa standart girişi tıkarlar ve başka bilgilerin girilmesini engellerler.

Bunun bir örneğini görmek için yukarıdaki programda ayrıca öğretmen sayısının da girilmesini isteyelim. Program düzenini biraz değiştirerek ve açıklamaları kaldırarak:

import std.stdio;

void main() {
    write("Okulda kaç öğrenci var? ");
    int öğrenci_sayısı;
    readf("%s", &öğrenci_sayısı);

    write("Kaç öğretmen var? ");
    int öğretmen_sayısı;
    readf("%s", &öğretmen_sayısı);

    writeln("Anladım: okulda ", öğrenci_sayısı, " öğrenci",
            " ve ", öğretmen_sayısı, " öğretmen varmış.");
}

Ne yazık ki program ikinci int'i okuyamaz:

Okulda kaç öğrenci var? 100
  ← Burada bir hata atılır

Kullanıcının girdiği 100'ün sonunda basılmış olan Enter'ın kodu girişte durmakta ve doğal olarak öğretmen_sayısı değişkeninin değeri olarak kullanılamamaktadır. Programın girişine gelen kodları şu şekilde ifade edebiliriz:

100[EnterKodu]

Bu durumda çözüm, öğretmen sayısından önce gelen Enter kodunun önemli olmadığını belirtmek için %s belirtecinden önce bir boşluk karakteri kullanmaktır: " %s". Düzen dizgisi içinde geçen boşluk karakterleri sıfır veya daha fazla sayıdaki görünmez kodu okuyup gözardı etmeye yararlar. O tek boşluk karakteri bütün görünmez karakter kodlarını okuyup gözardı eder: normal boşluk karakteri, Enter'la girilen satır sonu karakteri, Tab karakteri vs.

Genel bir kural olarak, okunan her değer için " %s" kullanabilirsiniz. Yukarıdaki program o değişiklikle artık istendiği gibi çalışır. Programın yalnızca değişen satırlarını gösteriyorum:

// ...
    readf(" %s", &öğrenci_sayısı);
// ...
    readf(" %s", &öğretmen_sayısı);
// ...

Çıktısı:

Okulda kaç öğrenci var? 100
Kaç öğretmen var? 20
Anladım: okulda 100 öğrenci ve 20 öğretmen varmış.
Ek bilgiler
Problem

Girişten sayı beklenen durumda harfler girin ve programın yanlış çalıştığını gözlemleyin.