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
- Daha önce gördüğümüz // karakterleri tek bir satır açıklama yazmaya elverişlidir. Birden fazla satırda blok halinde açıklama yazmak için açıklamayı /* ve */ belirteçleri arasına alabilirsiniz.
Başka açıklama belirteçlerini de içerebilmek için /+ ve +/ belirteçleri kullanılır:
/+ // Tek satırlık açıklama /* Birden fazla satırlık açıklama */ Yukarıdaki belirteçleri bile içerebilen açıklama bloğu +/
- Kaynak kodlardaki boşluk karakterlerinin çoğu önemsizdir. O yüzden fazla uzayan satırları bölebiliriz veya daha anlaşılır olacağını düşündüğümüz boşluklar ekleyebiliriz. Hatta yazım hatasına yol açmadığı sürece hiç boşluk kullanmayabiliriz bile:
import std.stdio;void main(){writeln("Okuması zor!");}
Fazla sıkışık kodu okumak güçtür.
Problem
Girişten sayı beklenen durumda harfler girin ve programın yanlış çalıştığını gözlemleyin.