Çıktı Düzeni
Diğer derslerden farklı olarak, bu bölüm D dilinin iç olanaklarıyla ilgili değil. Burada anlatılanlar tamamen kütüphane olanakları olarak gerçekleştirilmişlerdir ve Phobos'un çıktı düzeni için kullandığı std.format modülünün olanaklarıdır. Hazır değerler dersinde anlatılanlarla yakından ilgili olduğu için bu konuyu burada anlatmaya karar verdim.
D'nin giriş ve çıkış için kullandığı düzen belirteçlerinin temelde C dilindekiler gibi olduğunu ama bazı farkları bulunduğunu göreceksiniz.
Bir ön hatırlatma olarak :o), bütün düzen dizgisi karakterleri:
Ayar Karakterleri (birden fazla kullanılabilir)
- sola dayalı
+ işaretli
# diğer şekilde
0 solda 0'lı
boşluk solda boşluklu
Düzen Karakterleri
s belirteçsiz gibi
b ikili
d onlu
o sekizli
x,X onaltılı
e,E on üzerili
f,F virgüllü
g,G e veya f gibi
a,A onaltılı kesirli
Şimdiye kadar çıktı için writeln gibi işlevleri, gerektiğinde birden fazla parametreyle kullanmıştık. Bu parametreler otomatik olarak karakter eşdeğerlerine dönüştürülerek sırayla çıkışa gönderiliyorlardı.
Çoğu zaman bu yeterli olmaz. Çıktının belirli bir düzene uyması gerekebilir. Örneğin bir faturanın maddelerini yazdıran şu koda bakalım:
faturaMaddeleri ~= 1.23;
faturaMaddeleri ~= 45.6;
for (int i = 0; i != faturaMaddeleri.length; ++i) {
writeln("Madde ", i + 1, ": ", faturaMaddeleri[i]);
}
Çıktısı:
Madde 1: 1.23 Madde 2: 45.6
Oysa faturadaki değerlerin belirli bir düzende, örneğin her zaman için virgülden sonra iki haneyle ve geniş bir alanda sağa dayalı olarak yazılmaları okuma açısından önemli olabilir. (Not: Ben bu derste günlük kullanıma uygun olarak "virgül" diyeceğim; ama kesirli sayılarda virgül yerine nokta karakteri kullanılır.):
Madde 1: 1.23 Madde 2: 45.60
İşte çıktı düzeni, böyle konularda yarar sağlar. Şimdiye kadar kullandığımız ve isminde f harfi geçen çıktı işlevlerinin ilk parametresi bir düzen dizgisi olarak verilebilir. Bu işlevlerin isimlerindeki f harfi, "düzen, biçim" anlamına gelen "format"ın baş harfinden gelmiştir.
Örneğin yukarıdaki çıktıyı veren bir düzen dizgisi writefln ile şöyle yazılabilir:
writefln("Madde %d:%9.02f", i + 1, faturaMaddeleri[i]);
Düzen dizgisi, normal karakterlerden ve özel düzen belirteçlerinden oluşur. Her düzen belirteci % karakteriyle başlar ve bir düzen karakteri ile biter. Yukarıdaki dizgide iki tane düzen belirteci var: %d ve %9.02f.
Her belirteç, düzen dizgisinden sonra verilen parametrelerle sıra ile eşleşir. Örneğin %d ile i + 1, ve %9.02f ile faturaMaddeleri[i]... Her belirteç, eşleştiği parametrenin çıktı düzenini belirler.
Düzen dizgisi içinde bulunan ve belirteçlere ait olmayan karakterler, oldukları gibi yazdırılırlar. Yukarıdaki dizgi içindeki normal karakterleri kırmızı renkle şöyle gösterebiliriz: "Madde %d:%9.02f".
Düzen belirteci beş bölümden oluşur (Not: okumayı kolaylaştırmak için aralarında boşluk kullanıyorum; bu bölümler aslında bitişik olarak yazılırlar):
% ayar_karakterleri genişlik duyarlık düzen_karakteri
Baştaki % karakterinin ve sondaki düzen karakterinin yazılması şarttır, diğerleri ise isteğe bağlıdır.
% karakterinin böyle özel bir anlamı olduğu için, çıktıda % karakterinin kendisi yazdırılmak istendiğinde %% şeklinde çift olarak yazılır.
düzen_karakteri
b: tamsayı, ikili sayı düzeninde yazdırılır
o: tamsayı, sekizli sayı düzeninde yazdırılır
x ve X: tamsayı, onaltılı sayı düzeninde yazdırılır; x için küçük harfler, X için büyük harfler kullanılır
d: tamsayı, onlu sistemde yazdırılır; eğer işaretsiz bir türse ve değeri sıfırdan küçükse, başına eksi işareti gelir; aksi durumda işaretsiz bir tür gibi yazdırılır
int değer = 12; writefln("İkili : %b", değer); writefln("Sekizli : %o", değer); writefln("Onaltılı: %x", değer); writefln("Ondalık : %d", değer);
İkili : 1100 Sekizli : 14 Onaltılı: c Ondalık : 12
e: kesirli sayı, şu bölümlerden oluşacak şekilde yazdırılır
- virgülden önce tek hane
- duyarlık 0 değilse virgül
- virgülden sonra duyarlık adet hane (varsayılan duyarlık 6'dır)
ekarakteri- en az iki hane olarak "10 üzeri" anlamında üs değeri
E: e ile aynı düzende, ama çıktıda E harfiyle
f ve F: kesirli sayı, onlu sistemde yazdırılır; virgülden önce en az bir hane bulunur; varsayılan duyarlık 6'dır
g: kesirli sayı, eğer üs değeri -5 ile duyarlık arasında olacaksa, f gibi; değilse e gibi yazdırılır; duyarlık virgülden sonrasını değil, belirgin hane sayısını belirtir; virgülden sonra belirgin hane yoksa virgül de yazdırılmaz; virgülden sonra en sağdaki sıfırlar yazdırılmazlar
G: g ile aynı düzende, ama E veya F kullanılmış gibi yazdırılır
a: kesirli sayı, onaltılı sistemde ve şu bölümlerden oluşacak şekilde yazdırılır:
0xkarakterleri- tek onaltılı hane
- duyarlık 0 değilse virgül
- virgülden sonra duyarlık adet hane, veya duyarlık belirtilmemişse gerektiği kadar hane
pkarakteri- üssün değerine göre
-veya+karakteri - en az bir hane olarak "2 üzeri" anlamında üs değeri; (0 değerinin üs değeri 0'dır)
A: a ile aynı düzende, ama çıktıda 0X ve P karakterleriyle
double değer = 123.456789; writefln("e ile: %e", değer); writefln("f ile: %f", değer); writefln("g ile: %g", değer); writefln("a ile: %a", değer);
e ile: 1.234568e+02 f ile: 123.456789 g ile: 123.457 a ile: 0x1.edd3c07ee0b0bp+6
s: parametrenin değeri; düzen dizgisi kullanılmadığı zamandaki gibi, türüne uygun olan şekilde yazdırılır:
booltürlertrueveyafalseolarak- tamsayılar
%dgibi - kesirli sayılar
%ggibi - dizgiler UTF-8 kodlamasıyla; duyarlık, en fazla kaç bayt kullanılacağını belirler (UTF-8 kodlamasında karakter sayısıyla bayt sayısının eşit olmayabileceklerini hatırlayın; örneğin "ağ" dizgisi toplam 3 bayt uzunluğunda 2 karakterden oluşur)
- yapı ve sınıf nesneleri, türün
toString()üye işlevinin ürettiği dizgi olarak; duyarlık, en fazla kaç bayt kullanılacağını belirler - diziler, elemanları yan yana sıralanarak (bu ders yazıldığı sırada
std.stream.writeflnilestd.stdio.writeflnbu konuda farklılık gösteriyorlar)
bool b = true; int tamsayı = 365; double kesirli = 9.87; string dizgi = "düzenli"; auto nesne = new std.stream.File("deneme_dosyası", FileMode.OutNew); int[] dizi = [ 2, 4, 6, 8 ]; writefln("%s", b); writefln("%s", tamsayı); writefln("%s", kesirli); writefln("%s", dizgi); writefln("%s", nesne); writefln("%s", dizi);
true 365 9.87 düzenli std.stream.File 2 4 6 8
genişlik
Değer için çıktıda ayrılan alanın genişliğini belirler. Eğer genişlik olarak * kullanılmışsa, genişlik değeri bir sonraki parametrenin değeri olarak alınır. Eğer eksi bir sayıysa, - ayar karakteri kullanılmış gibi çalışır.
int değer = 100; writefln("On karakterlik alanda :%10s", değer); writefln("Beş karakterlik alanda:%5s", değer);
On karakterlik alanda : 100 Beş karakterlik alanda: 100
duyarlık
Eğer belirtilmişse, nokta karakterinden sonra yazılır. Kesirli sayı türünden olan değerlerin çıktıda kullanılacak olan duyarlığını belirler. Eğer duyarlık olarak * kullanılmışsa, duyarlık değeri bir sonraki parametrenin değeri olarak alınır (o değer int olmak zorundadır). Duyarlık eksi bir sayıysa gözardı edilir.
double kesirli = 1234.56789; writefln("%.8g", kesirli); writefln("%.3g", kesirli); writefln("%.8f", kesirli); writefln("%.3f", kesirli);
1234.5679 1.23e+03 1234.56789000 1234.568
auto sayı = 0.123456789; writefln("Sayı: %.*g", 4, sayı);
Sayı: 0.1235
ayar_karakterleri
Birden fazla ayar karakteri kullanabilirsiniz.
-: parametre değeri; kendisine ayrılan alanda sola dayalı olarak yazdırılır; bu ayar, 0 ayar karakterini geçersiz kılar
int değer = 123; writefln("normalde sağa dayalı:|%10d|", değer); writefln("sola dayalı :|%-10d|", değer);
normalde sağa dayalı:| 123| sola dayalı :|123 |
+: değer artı ise başına + karakteri yazdırılır; bu ayar, boşluk ayar karakterini geçersiz kılar
writefln("eksi değerde etkili değil: %+d", -50); writefln("artı değer, + ile : %+d", 50); writefln("artı değer, + olmadan : %d", 50);
eksi değerde etkili değil: -50 artı değer, + ile : +50 artı değer, + olmadan : 50
#: kullanılan düzen_karakteri'ne bağlı olarak, değeri başka şekilde yazdırır
oiçin: sekizli sayının ilk karakteri her zaman için 0 olarak yazdırılırxveXiçin: sayı sıfır değilse, başına0xveya0Xgelir- kesirli sayılarda: virgülden sonra hane olmasa da virgül yazdırılır
gveGiçin: virgülden sonra sağdaki sıfırlar atılmaz
writefln("Sekizli sıfırla başlar : %#o", 1000); writefln("Onaltılının başına 0x gelir : %#x", 1000); writefln("Gerekmese de virgüllü : %#g", 1f); writefln("Sağdaki sıfırlar da yazdırılır: %#g", 1.2);
Sekizli sıfırla başlar : 01750 Onaltılının başına 0x gelir : 0x3e8 Gerekmese de virgüllü : 1.00000 Sağdaki sıfırlar da yazdırılır: 1.20000
0: sayılarda (değer nan veya infinity değilse), sol tarafa değer için ayrılan alan dolacak kadar 0 yazdırılır; duyarlık da belirtilmişse bu ayar etkisizdir
writefln("Sekiz genişlikte: %08d", 42);
Sekiz genişlikte: 00000042
boşluk karakteri: değer artı ise, eksi değerlerle alt alta düzgün dursun diye başına tek bir boşluk karakteri yazdırılır
writefln("Eksi değerde etkisi yok: % d", -34); writefln("Artı değer, boşluklu : % d", 56); writefln("Artı değer, boşluksuz : %d", 56);
Eksi değerde etkisi yok: -34 Artı değer, boşluklu : 56 Artı değer, boşluksuz : 56
Problemler
- Girilen tamsayıyı onaltılı düzende yazdıran bir program yazın.
- Girilen kesirli sayıyı bir yüzde değeri olarak ve virgülden sonra 2 haneyle yazdıran bir program yazın. Örneğin 1.2345 girildiğinde ekrana yalnızca
%1.23yazsın.
D.ershane
Forum
Wiki
Projeler
Tanıtım
İletişim
Hakları