4.4.4.5 Sayılar için Biçim Dizesi Bileşenleri Bu tür formatString bileşeninin iki alt türü vardır: standart-tanımlı biçimler ve kullanıcı-tanımlı biçimler (özel biçim dizeleri).
4.4.4.6 Sayılar için Standart Biçimler Bu biçimler çok sayıda biçim belirteçlerinden biri ile tanımlanır, bunlar özel öneme sahip harflerdir. Biçim belirtecinden sonra duyarlılık olarak adlandırılan bir pozitif tamsayı olabilir, duyarlılığın farklı belirteçler için farklı anlamı vardır. Ondalık noktadan sonraki ondalık basamak sayısını etkilediğinde, sonuç yuvarlanır. Aşağıdaki tablo, belirteçleri ve bunların duyarlılık anlamını anlatmaktadır:
Belirteç
Açıklama
"C" veya "c"
Para gösterir ve sonuç geçerli "kültür" (örneğin, İngilizce) için para işareti ile birlikte görüntülenir. Duyarlılık ondalık noktadan sonraki ondalık basamak sayısını gösterir.
"D" veya "d"
Bir tamsayı. Duyarlılık dizeyi temsil için gerekli minimum karakter sayısını gösterir ve eğer gerekli ise, sıfır başlangıçta ilave edilir.
"E" veya "e"
Üslü gösterim. Duyarlılık ondalık noktadan sonraki basamak sayısını gösterir.
"F" veya "f"
Tamsayı veya ondalık sayı. Duyarlılık ondalık noktadan sonraki işaretlerin sayısını gösterir.
"N" veya "n"
"F" eşdeğeridir, aynı zamanda binler, milyonlar, vb için ilgili ayırıcıyı temsil eder (örneğin, İngilizce dilinde sık sık numarası "1000" sayısı "1,000" olarak temsil edilir; 1 ve sıfır arasında virgül ile).
"P" veya "p"
Yüzde: sayıyı 100 ile çarpar ve yüzde karakterini başta gösterir. Duyarlılık ondalık noktadan sonraki işaretlerin sayısını gösterir.
"X" veya "x"
Onaltılık sayı sisteminde sayıyı görüntüler. Sadece tamsayılar için çalışır. Duyarlılık dizeyi görüntülemek için gerekli minimum işaret sayısını belirtir, eksik olanlar başlangıçta sıfır ile takviye edildiği gibidir.
Biçimlendirmenin bir parçası da işletim sisteminin bölgesel ayarlarından varsayılan olarak alınan geçerli "kültür" ayarları tarafından belirlenmektedir. "Kültürler" belirli bir dil ya da belirli bir ülke için geçerli olan kurallardır ve ondalık ayırıcı olarak kullanılacak olan karakteri, paranın nasıl görüntüleneceğini, vb. belirtirler. Örneğin, Japon "kültür"ü için para miktarından sonra "¥" eklenerek görüntülenir. Amerikan "kültür"ü için, "$" karakteri miktardan önce görüntülenirken, Bulgar para birimi için görüntülenen sonek ise "лв." olarak belirlenmişir. 4.4.4.7 Standart Sayı Biçimleri – Örnek Yukarıdaki tabloda gösterilen belirteçlerinin kullanımını birkaç örnek ile görelim. Kodda bölgesel ayarlar Bulgaristan olarak ayarlıdır, bu nedenle Bulgaristan para birimi basılacaktır. Ondalık ayırıcı "," olacak ve binler basamağının ayırıcısı boşluk karakteri olacaktır. (Bölgesel ayarlar Windows Denetim Masası'ndan değiştirilebilir):
StandardNumericFormats.cs
class StandardNumericFormats
{
static void Main()
{
Console.WriteLine("{0:C2}", 123.456);
//Output: 123,46 лв.
Console.WriteLine("{0:D6}", -1234);
//Output: -001234
Console.WriteLine("{0:E2}", 123);
//Output: 1,23E+002
Console.WriteLine("{0:F2}", -123.456);
//Output: -123,46
Console.WriteLine("{0:N2}", 1234567.8);
//Output: 1 234 567,80
Console.WriteLine("{0:P}", 0.456);
//Output: 45,60 %
Console.WriteLine("{0:X}", 254);
//Output: FE
}
}
Aynı kodu İngiliz (A.B.D) kültürü ile çalıştırırsanız, çıktısı aşağıdaki gibi olacaktır:
$123.46
-001234
1.23E+002
-123.46
1,234,567.80
45.60 %
FE
4.4.4.8 Sayılar için Özel Biçimler Standart olmayan tüm biçimler kullanıcı (özel) biçimleri olarak atanır. Özel biçimler için yine bir dizi belirteç tanımlanmıştır ve standart biçimler ile farkı birden fazla belirteç kullanılabilir (standart formatlarda tek bir belirteç kullanılır). Aşağıdaki tablo çeşitli belirteçleri ve bunların anlamlarını listeler:
:
Specifier
Description
0
Bir basamağı gösterir. Sonuçta bu pozisyondaki basamak eksikse, yerine sıfır yazılır.
#
Bir basamağı gösterir. Sonuç olarak, bu konumdaki rakam eksikse şey yazmaz.
.
İlgili "kültür" için ondalık ayırıcı.
,
İlgili "kültür" için binler basamağı ayırıcısı.
%
Sonucu 100 ile çarpar ve yüzde karakterini basar.
E0 veya E+0 veya E-0
Üssel gösterimi belirtir. Sıfır sayısı üs işaretlerinin sayısını göstermektedir. "+" işareti her zaman sayının işaretini de temsil etmek istediğimiz anlamına gelir, eksi değer negatif olması durumunda işareti görüntülemek anlamına gelir.
Sayılar için özel biçimlerin kullanımı ile ilgili pek çok özellik vardır, ancak burada ele alınmayacaktır. MSDN’den daha fazla bilgiyi bulabilirsiniz. Özel biçimlendirme dizelerinin nasıl kullanılacağını gösteren bazı basit örnekleri aşağıda bulacaksınız (çıktı A.B.D kültürü için verilmiştir):
4.4.4.9 Tarihler için Biçim Dizesi Tarihleri biçimlendirirken de standart ve özel formatların ayrımından söz edeceğiz. 4.4.4.10 Standart Tanımlı Tarih Biçimleri Standart tanımlı biçimlerin sayısı çok olduğu için sadece onların birkaçını listeleyeceğiz. Kalanı kolaylıkla MSDN üzerinden gözden geçirilebilir.
Belirteç
Biçim (İngiliz (A.B.D) "kültürü" için)
d
2/27/2012
D
February 27, 2012
t
17:30 (saat)
T
17:30:22 (saat)
Y veya y
February 2012 (sadece ay ve yıl)
4.4.4.11 Özel Tarih Biçimleri Sayılar için özel biçimlerde olduğu gibi burada da çoklu biçim belirteçlerinden söz edeceğiz ve onların birkaçını birleştireceğiz. Burada çok sayıda belirteç olduğu için tarihler için özel biçimlerin nasıl kullanılacağını göstermek için bunlardan sadece bazılarını göstereceğiz. Aşağıdaki tabloyu düşünün:
Belirteç
Biçim (İngiliz (A.B.D) "kültürü" için)
D
Gün –1’den 31’e kadar
dd
Gün – 01’den 31’e kadar
M
Ay – 1’den 12’e kadar
MM
Ay – 01’den 12’e kadar
yy
Yılın son iki basamağı (00’dan 99’a kadar)
yyyy
4 basamaklı yazılan Yıl (örneğin 2012)
hh
Saat –00’dan 11’e kadar
HH
Saat –00’dan 23’e kadar
m
Dakika – 0’dan 59’a kadar
mm
Dakika – 00’dan 59’a kadar
s
Saniye – 0’dan 59’a kadar
ss
Saniye – 00’dan 59’a kadar
Bu belirteçler kullanıldığında, tarihin farklı parçaları arasına farklı ayırıcılar ekleyebilirsiniz, "." yada "/" gibi. İşte birkaç örnek:
DateTime d = new DateTime(2012, 02, 27, 17, 30, 22);
Console.WriteLine("{0:dd/MM/yyyy HH:mm:ss}", d);
Console.WriteLine("{0:d.MM.yy}", d);
Bu örneklerden çalıştırılması İngiliz kültürü için aşağıdaki sonucu verir:
27/02/2012 17:30:22
27.02.12
Sonuç geçerli kültüre bağlı olarak değişebilir, unutmayın. Örneğin, Bulgar kültüründe aynı kodu çalıştırırsanız sonuç farklı olacaktır:
27.02.2012 17:30:22
27.02.12
4.4.4.12 Birer Birer Sayılan Türler için Biçim Dizesi Bileşenleri Birer birer sayılan (listelenmiş türler) önceden tanımlanmış birçok olası değerden birini alabilen veri türleridir (örneğin haftanın yedi günü). "Sınıfları Tanımlama" Bölümü’nde detaylı olarak bunları inceleyeceğiz. Numaralandırma biçimlendirilmesinde anlatacak çok az şey var. Dört standart biçim belirteçleri tanımlanmıştır:
Belirteç
Biçim
G veya g
Dize olarak numaralandırmayı temsil eder.
D veya d
Sayı olarak numaralandırmayı temsil eder.
X veya x
Onaltılık sayı sisteminde bir sayı olarak ve sekiz basamaklı numaralandırmayı temsil eder.
İşte bazı örnekler:
Console.WriteLine("{0:G}", DayOfWeek.Wednesday);
Console.WriteLine("{0:D}", DayOfWeek.Wednesday);
Console.WriteLine("{0:X}", DayOfWeek.Wednesday);
Yukarıdaki kod çalıştırılırken şu sonucu alırsınız:
Wednesday
3
00000003
4.4.4.13 Biçimlendirme Dizeleri ve Yerelleştirme Biçim dizelerini kullanırken bir ve aynı program işletim sisteminin yerelleştirme ayarlarına bağlı olarak farklı değerler yazdırabilir. Örneğin, belirli bir tarihteki ay yazdırılırken mevcut yerelleştirme İngiliz ise örneğin "August" yazdıracak, Fransız ise örneğin "Août" yazdıracaktır. Bir konsol uygulaması başlatılırken otomatik olarak işletim sistemi lokalizasyonunu alır (kültür ayarları) ve (sayılar, tarihler, para, vb) biçimlendirilmiş verileri okumak ve yazmak için kullanır. .NET yerelleştirmesine de "kültür" denir ve System.Globalization.CultureInfo sınıfı tarafından manuel olarak elle değiştirilebilir. A.B.D ve Bulgar yerelleştirmesi tarafından bir sayı ve bir tarihin yazdırılmasına örnek aşağıda verilmiştir:
CultureInfoExample.cs
using System;
using System.Threading;
using System.Globalization;
class CultureInfoExample
{
static void Main()
{
DateTime d = new DateTime(2012, 02, 27, 17, 30, 22);
Thread.CurrentThread.CurrentCulture =
CultureInfo.GetCultureInfo("en-US");
Console.WriteLine("{0:N}", 1234.56);
Console.WriteLine("{0:D}", d);
Thread.CurrentThread.CurrentCulture =
CultureInfo.GetCultureInfo("bg-BG");
Console.WriteLine("{0:N}", 1234.56);
Console.WriteLine("{0:D}", d);
}
}
Örnek başlatılırken aşağıdaki sonuç elde edilir:
1,234.56
Monday, February 27, 2012
1 234,56
27 Февруари 2012 г.
4.5 Konsol Girdisi Bu bölümün başında açıkladığımız gibi, küçük uygulamalar için en uygun olanı konsol iletişimidir, çünkü bunu uygulamak en kolayıdır. Standart girdi aygıtı programın kendi giriş bilgilerini alabileceği yeri kontrol eden işletim sisteminin bir parçasıdır. Varsayılan olarak "standart girdi aygıtı" klavyeye "bağlı" bir sürücüden bilgi girişini okur. Bu değiştirilebilir ve standart giriş başka bir yere, örneğin bir dosyaya yönlendirilebilir, ancak bu nadiren yapılır. Her programlama dili konsola okuma ve yazmak için bir mekanizmaya sahiptir. C# standart girdi akışını kontrol eden nesne Console.In olarak tanımlıdır. Konsoldan farklı verileri okuyabilirsiniz:
metin;
metni ayrıştırma sonrasında diğer türler;
Aslında standart giriş akımını okumak için Console.In nadiren doğrudan kullanılır. Console sınıfı bu akım üzerinden çalışan iki yöntem sağlar, Console.Read() ve Console.ReadLine(), ve konsoldan okuma genellikle onlar tarafından yapılır.
4.5.1 Console.ReadLine() Aracılığıyla Okuma Console.ReadLine() yöntemi konsoldan okumak için büyük kolaylık sağlar. Nasıl çalışır? Bu yöntem çağrıldığında, program çalışmasını durdurur ve konsoldan giriş için bekler. Kullanıcı konsoldan bazı dizeleri girer ve [Enter] tuşuna basar. İşte bu anda kullanıcının konsoldan veri girişini bitirdiğini anlar ve dizeyi okur. Console.ReadLine() yöntemi kullanıcı tarafından girilen dizeyi sonuç olarak döndürür. Yöntemin bu ada sahip olmasının nedeni belki de şimdi daha açık olmuştur. Aşağıdaki örnek, Console.ReadLine() çalışmasını gösterir:
UsingReadLine.cs
class UsingReadLine
{
static void Main()
{
Console.Write("Please enter your first name: ");
string firstName = Console.ReadLine();
Console.Write("Please enter your last name: ");
Console.ReadLine() metotunu kullanarak konsoldan metin okumanın ne kadar kolay olduğunu görüyoruz:
Kullanıcı adı sorulduktan sonra konsola metin gireriz (bu sadece kullanıcının kolaylığı içindir ve zorunlu değildir).
ReadLine() metotunu kullanarak konsoldan bütün bir satır okutulur. Kullanıcı metin girip [Enter] tuşuna basana kadar programın çalışması engellenir.
Sonra soyadı için bu iki adım tekrarlanır.
Gerekli bilgileri topladıktan sonra konsolda yazdırabilirsiniz.
4.5.2 Console.Read() Aracılığıyla Okuma Read() yöntemi ReadLine() yönteminden biraz daha farklı davranır. Başlangıç olarak tüm satırı değil, sadece bir karakter okur. İki yöntem arasındaki diğer önemli fark, okunan karakterin doğrudan dönmemesi, ancak kodun döndürülmesidir. Sonucu karakter olarak kullanmak istiyorsanız karaktere dönüştürmemiz gerekir veya üzerinde Convert.ToChar() metotunu kullanırız. Önemli bir özelliği vardır: karakter [Enter] tuşuna basıldığında salt-okunur haldedir. Sonra konsolda yazılı tüm dize standart giriş dizesinin arabelleğine aktarılır ve Read() yöntemi bunun ilk karakterini okur. Yöntemin sonraki çağrılarında, arabellek boş değilse, (yani zaten girilmiş, ancak hâlâ okunmamış karakterler varsa) program çalışması durmayacak ve beklemeyecektir, ancak bu arabellek boşalana kadar doğrudan sonraki karakteri arabellekten okuyacaktır. Ancak Read() tekrar çağrılırsa ancak o zaman program kullanıcı girişi için tekrar bekleyecektir. İşte bir örnek:
UsingRead.cs
class UsingRead
{
static void Main()
{
int codeRead = 0;
do
{
codeRead = Console.Read();
if (codeRead != 0)
{
Console.Write((char)codeRead);
}
}
while (codeRead != 10);
}
}
Bu program, kullanıcı tarafından girilen bir satırı okur ve karakter karakter yazdırır. Bu durum, küçük bir hile mümkündür – daha önce farkındayız ki [Enter] tuşu aslında arabelleğe iki karakter girer. Bunlar "satır başı" kodunu (Unicode 13) takiben "satır besleme" kodudur (Unicode 10). Bir satırın bittiğini anlamak için Unicode tablosunda kodu 10 olan bir karakteri arıyoruz. Böylece program sadece bir satırı okur ve döngüden çıkar. Console.Read() metotunun Console.ReadLine() kullanmak için bir alternatifiniz varsa, pratikte nadiren kullanıldığından bahsetmeliyiz. Bunun nedeni, alternatif bir yaklaşımı seçmek ile kıyaslandığında Console.Read() ile hata yapma olasılığının çok daha büyük olmasıdır ve kod büyük olasılıkla gereksiz yere karmaşık olacaktır.
4.5.3 Sayıları Okuma C# dilinde konsoldan sayıları okuma doğrudan yapılmaz. Bir sayıyı okumak için girdiyi daha önce bir dize olarak okumanız (ReadLine() kullanarak) ve daha sonra bu dizeyi sayıya dönüştürmeniz gerekir. Bir dizeyi başka bir tür içine dönüştürme işlemine ayrıştırma denir. Tüm temel türlerin ayrıştırma yöntemleri vardır. Bir sayıyı okuyan ve ayrıştıran basit bir örnek aşağıda verilmiştir:
ReadingNumbers.cs
class ReadingNumbers
{
static void Main()
{
Console.Write("a = ");
int a = int.Parse(Console.ReadLine());
Console.Write("b = ");
int b = int.Parse(Console.ReadLine());
Console.WriteLine("{0} + {1} = {2}", a, b, a + b);
Console.WriteLine("{0} * {1} = {2}", a, b, a * b);
Console.Write("f = ");
double f = double.Parse(Console.ReadLine());
Console.WriteLine("{0} * {1} / {2} = {3}",
a, b, f, a * b / f);
}
}
Program çalıştırılmasının sonucu aşağıdaki gibidir (Girdi olarak 5, 6 ve 7,5 girmek şartıyla):
a = 5
b = 6
5 + 6 = 11
5 * 6 = 30
f = 7.5
5 * 6 / 7.5 = 4
Bu özel örnekte, dikkat etmemiz gereken şey sayısal türleri ayrıştırma yöntemlerini kullanırken yanlış sonuç geçirilirse (metin gibi) bunun System.FormatExceptionhatasına (istisna) neden olmasıdır. Özellikle gerçek sayıları okurken bu doğrudur, çünkü bütün ve kesirli kısımlar arasında kullanılan ayırıcı çeşitli kültürlerde farklıdır ve işletim sisteminin bölgesel ayarlarına bağlıdır.
Kayan noktalı sayılar için ayırıcı işletim sisteminin geçerli dil ayarlarına bağlıdır (Windows Bölge ve Dil Seçenekleri). Ayırıcı olarak bazı sistemlerde karakter virgül kullanılabilir, diğerlerinde - nokta. Virgül yerine nokta girmek geçerli dil ayarları virgülü kullanıyorsa System.FormatException istisnasına neden olacaktır.
Raporlama hataları için bir mekanizma olarak istisnalar "İstisnai Durum İşleme" Bölümü’nde ele alınacaktır. Şimdilik program bir hata sağladığı zaman bunun hata hakkında ayrıntılı bilgiyi konsolda yazdıran bir istisna oluşumu ile ilişkili olduğunu düşünebilirsiniz. Örneğin, bilgisayarın bölgesel ayarları Bulgaristan’a ayarlı iken aşağıdaki kodu çalıştırdığımızı varsayalım:
Console.Write("Enter a floating-point number: ");
string line = Console.ReadLine();
double number = double.Parse(line);
Console.WriteLine("You entered: {0}", number);
"3.14" sayısını girerseniz (Bulgar ayarları için yanlış bir ondalık ayırıcı)aşağıdaki istisnai durumu (hata mesajı) alacaksınız:
Unhandled Exception: System.FormatException: Input string was not in a correct format.
at System.Number.ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
at System.Double.Parse(String s, NumberStyles style, NumberFormatInfo info)
at System.Double.Parse(String s)
at ConsoleApplication.Program.Main() in C:\Projects\IntroCSharpBook\ConsoleExample\Program.cs:line 14
4.5.4 Sayıları Koşullu Ayrıştırma Int32.Parse(string)veya Convert.ToInt32(string) metotunu kullanarak bir dizeyi bir sayıya ayrıştırdığınız zaman gönderilen dize sayı değilse bir istisna alınır. Bazen başarısız ayrıştırmayı yakalamak ve bir hata mesajı yazdırmak için veya yeni bir değer girmek için kullanıcıya sormak gereklidir. Ayrıştırırken yanlış girilen sayının engellenmesi iki şekilde yapılabilir:
istisnai durumları yakalayarak (bkz. "İstisnai Durum İşleme" Bölümü);
koşullu ayrıştırma ile (TryParse (...) metotunu kullanarak).
.NET Framework sayılarının koşullu ayrıştırılmasını düşünelim. Int32.TryParse (...) yöntemi iki parametre kabul eder – bir ayrıştırma dizesi ve ayrıştırma sonucunu kaydetmek için bir değişken. Ayrıştırma başarılı olursa yöntem true değerini döndürür. Daha fazla netleştirmek için bir örnek düşünelim:
string str = Console.ReadLine();
int intValue;
bool parseSuccess = Int32.TryParse(str, out intValue);
Console.WriteLine(parseSuccess ?
"The square of the number is " + intValue * intValue + "."
: "Invalid number!");
Örnekte, konsoldan girilen bir dizenin Int32 tamsayı türüne koşullu ayrıştırması yapılmıştır. Girdi olarak "2" olarak girerseniz ayrıştırma başarılı olacaktır ve TryParse() sonucu true olacaktır, ve ayrıştırılan sayı intValue değişkenine kaydedilecektir ve konsolda sayının karesi basılacaktır:
Result: The square of the number is 4.
"abc" gibi geçersiz bir sayıyı ayrıştırmaya çalışırsanız, TryParse() sonucu false olarak dönecektir ve kullanıcıya geçersiz sayı girmiş olduğu bildirilir.
Invalid number!
TryParse() yöntemi, çalışmasının bir sonucu olarak, aynı anda iki değer döndürür: ayrıştırılan sayı (bir çıkış parametresi olarak) ve yöntemin çağrılmasının bir sonucu olarak bir Boole değer. Birden fazla değer döndürmek mümkündür, çünkü değerlerden biri bir çıkış parametresi (out parametresi) olarak döndürülür. Çıkış parametreleri kendi türü ile çakışan ve önceden tanımlanmış bir değişken için değer döndürür. Bir yöntem çağrılırken çıkış parametrelerinin önüne out anahtar sözcüğü gelmelidir.
4.5.5 Console.ReadKey() ile Okuma Console.ReadKey() yöntemi konsolda bir tuşa basılmasını bekler ve [Enter] tuşuna basılmasına gerek olmadan karakter eşdeğerini okur. ReadKey() çağrılmasının sonucu basılan tuş hakkında (yada daha doğrusu bir tuş kombinasyonu) bir ConsoleKeyInfo nesnesi olarak bilgi almaktır. Elde edilen nesne basılan tuş kombinasyonu ile girilen karakteri içerir (KeyChar özelliği), [Shift], [Ctrl] ve [Alt] (Modifiers özelliği) tuşları hakkında bilgilerle birlikte. Örneğin [Shift+A] tuşuna basıldığında büyük harf 'A' okuyacaktır ve Modifiers özelliği Shift bayrağı olacaktır. İşte bir örnek:
Biz programı çalıştırdığınızda ve [Shift+A] bastığınızda şu sonucu elde edersiniz:
A
Character entered: A
Special keys: Shift
4.5.6 Nakov.IO.Cin yoluyla Sayıları Basitleştirilmiş Okuma Bir boşlukla ayrılmış, aynı satır üzerinde yer alan birkaç sayıyı okumanın standart kolay bir yolu yoktur. C# ve .NET Framework’te bir dize olarak okuduktan sonra ayırıcı olarak boşluk karakterini kullanarak belirteçlere bölmek ve sayıları ayıklamak için elde edilen belirteçleri ayrıştırmanız gerekmektedir. C++ gibi diğer dillerde ve platformlarda doğrudan ayrıştırma olmadan konsoldan sayıları, karakterleri ve metin okuyabilirsiniz. Bu C# dilinde mevcut değildir, ancak bir harici kitaplık veya sınıfını kullanabilirsiniz. Nakov.IO.Cin standart kütüphanesi konsoldan sayıları okumak için basitleştirilmiş bir yol sağlar. Svetlin Nakov’un blogunu bu konuda okuyabilirsiniz: http://www.nakov.com/blog/2011/11/23/cin-class-for-csharp-read-from-console-nakov-io-cin/. Visual Studio C# projeniz içine Nakov.IO.Cin ’den gelen Cin.cs dosyasını kopyaladıktan sonra, şunun gibi bir kod yazabilirsiniz:
using Nakov.IO;
...
int x = Cin.NextInt();
double y = Cin.NextDouble();
decimal d = Cin.NextDecimal();
Console.WriteLine("Result: {0} {1} {2}", x, y, d);
Kodu çalıştırırsanız, aralarında istenilen miktarda boşluk ayırıcı konulmuş 3 sayıyı girebilirsiniz. Mesela ilk sayı, iki boşluk, ikinci sayı, yeni bir satır + boşluk ve son sayı + boşluk girebilirsiniz. Sayılar doğru okunacak ve aşağıdaki gibi çıktısı olacaktır:
3 2.5
3.58
Result: 3 2.5 3.58
4.6 Konsol Giriş ve Çıkış – Örnekler Konsol giriş ve çıkışı ile ilgili bazı ilginç teknikler gösteren birkaç örneği şimdi ele alacağız.
4.6.1 Bir Mektup Yazdırma Bu örnek konsol girişini ve biçimlendirilmiş metni bir mektup bağlamında gösteren pratik bir örnektir.
PrintingLetter.cs
class PrintingLetter
{
static void Main()
{
Console.Write("Enter person name: ");
string person = Console.ReadLine();
Console.Write("Enter book name: ");
string book = Console.ReadLine();
string from = "Authors Team";
Console.WriteLine(" Dear {0},", person);
Console.Write("We are pleased to inform " +
"you that \"{1}\" is the best Bulgarian book. {2}" +
"The authors of the book wish you good luck {0}!{2}",
Yukarıdaki programın çalıştırılmasının sonucu şu olabilir:
Enter person name: Readers
Enter book name: Introduction to programming with C#
Dear Readers,
We are pleased to inform you that "Introduction to programming with C#" is the best Bulgarian book.
The authors of the book wish you good luck Readers!
Yours,
Authors Team
Bu örnekte bir mektup şablonu var. Program kullanıcıya birkaç soru "sorar" ve biçimlendirme belirteçlerini kullanıcı tarafından doldurulan verilerle değiştirerek mektubu yazdırmak için gerekli bilgileri konsoldan okur. 4.6.2 Bir Dikdörtgen veya Üçgenin Alanı Başka bir örnek ele alacağız: bir dikdörtgen yada üçgenin alanının hesaplanması.
CalculatingArea.cs
class CalculatingArea
{
static void Main()
{
Console.WriteLine("This program calculates " +
"the area of a rectangle or a triangle");
Console.WriteLine("Enter a and b (for rectangle) " +
"or a and h (for triangle): ");
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
Console.WriteLine("Enter 1 for a rectangle or " +
"2 for a triangle: ");
int choice = int.Parse(Console.ReadLine());
double area = (double) (a * b) / choice;
Console.WriteLine("The area of your figure is " + area);
}
}
Yukarıdaki örneğin çalıştırılmasının sonucu aşağıdaki gibidir:
This program calculates the area of a rectangle or a triangle
Enter a and b (for rectangle) or a and h (for triangle):
5
4
Enter 1 for a rectangle or 2 for a triangle:
2
The area of your figure is 10
4.7 Alıştırmalar
Konsoldan int türünde üç sayıokuyan ve bunların toplamını yazdıran bir program yazın.
Konsoldan bir çemberin yarıçapı "r" okuyan ve onun çevre ve alanını yazdıran bir program yazın.
Verilen bir şirketin adı, adresi, telefon numarası, faks numarası, web sitesi ve yöneticisi vardır. Yöneticinin adı, soyadı ve telefon numarası vardır. Şirket ve yöneticisi hakkında bilgi okuyan ve sonra konsolda yazdıran bir program yazın.
Konsolda üç sanal sütuna üç sayı yazdıran bir program yazın. Her sütun 10 karakter bir genişliğe sahip olmalıdır ve sayılar sola doğru hizalanmalıdır. İlk sayı onaltılık bir tamsayı olmalıdır; ikinci sayı pozitif kesir olmalıdır; ve üçüncü sayı negatif kesir olmalıdır. Son iki sayının ikinci ondalık basamağa yuvarlanması gerekiyor.
Konsoldan iki tamsayıyı (int) okuyan ve bunların arasında 5 ile kendi bölündüğünde 0 kalan veren kaç adet sayı olduğunu yazdıran bir program yazın. Örnek: (14, 25) aralığı içinde böyle 3 sayı bulunmaktadır: 15, 20 ve 25.
Konsoldan iki sayıyı okuyan ve bunların daha büyük olanını yazdıran bir program yazın. Koşullu ifadeler kullanmadan bu problemi çözün.
Beş sayı okuyan ve bunların toplamını yazdıran bir program yazın. Geçersiz bir sayı girilirse program başka bir sayı girmesi için kullanıcıdan istemde bulunmalıdır.
Konsoldan beş sayı okuyan ve bunların en büyüğünü yazdıran bir program yazın.
Konsoldan bir tamsayı n okuyan bir program yazın. Program bundan sonra konsoldan n adet sayı okuyup bunların toplamını yazdıracaktır.
Konsoldan bir tamsayı n okuyan ve [1...n] aralığındaki tüm sayıları, her biri ayrı bir satırda olmak üzere yazdıran bir program yazın.
Fibonacci dizisinin ilk 100 sayısını konsolda yazdıran bir program yazın: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, …
Aşağıdaki dizinin (0,001 duyarlılıkla) toplamını hesaplayan bir program yazın: 1 + 1/2 - 1/3 + 1/4 - 1/5 + …
Bölüm 5. Koşullu İfadeler
5.1 Bölümün İçindekileri Bu bölüm C# dilinde verilen bir duruma bağlı olarak farklı eylemleri yürütmek için kullanabileceğiniz koşullu ifadeleri içeriyor. if ve if-else koşullu işleçlerinin sözdizimini uygun örneklerle açıklayacağız ve switch-case seçim işlecinin pratik uygulamasını anlatacağız. Koşullu ifadelerin iç içe yada diğer türleri kullanıldığında daha iyi bir programlama stiline ulaşmak için izlenecek en iyi uygulamalar üzerinde duracağız.
5.2 Karşılaştırma İşleçleri ve Boole İfadeleri Aşağıdaki bölümde C# dilindeki temel karşılaştırma işleçlerini hatırlayacağız. Onlar önemlidir, çünkü koşullu durumları tanımlamak için kullanılırlar. 5.2.1 Karşılaştırma İşleçleri C# dilinde tamsayılar çiftlerini, kayan noktalı sayıları, karakterleri, dizeleri ve diğer türleri karşılaştırmak için kullanılan birkaç karşılaştırma işleci tanımlıdır:
İşleç
Etkisi
==
Eşittir
!=
Eşit değildir
>
Büyüktür
>=
Büyük veya eşittir
<
Küçüktür
<=
Küçük veya eşittir
Karşılaştırma işleçleri iki sayıyı, iki sayısal ifadeyi veya bir sayı ve bir değişken gibi ifadeleri karşılaştırmak için kullanılabilir. Karşılaştırma sonucu bir Boole değeridir (true veya false).
Karşılaştırmaların kullanıldığı bir örneğe bakalım:
Örnek kodda biz sayılar arasında ve karakterler arasında bir karşılaştırma yapıyoruz. Sayılar büyüklüğüne göre karşılaştırılırken, karakterler sözlüksel sıralarına göre karşılaştırılırlar (Karakterlere karşılık gelen Unicode kodları kullanılmıştır). Örnekten görüldüğü gibi, char türü bir sayı gibi davranır, ve numaralarla toplama, çıkarma ve karşılaştırma işlemlerine serbestçe girebilirler. Ancak, bu dikkatli şekilde kullanılmalıdır, çünkü kodun okunması ve anlaşılması zorlaşabilir. Örnek çalıştırıldığında aşağıdaki çıktıyı verecektir:
True
False
True
True
True
C# dilinde çeşitli veri türlerinin karşılaştırılması mümkündür:
nesne işaretçileri olarak da bilinen nesnelere referanslar, (string, object, diziler ve diğerleri)
Her karşılaştırma, iki sayıyı, iki bool değeri yada iki nesne referansını etkileyebilir. Örneğin, bir kayan noktalı sayı ile tamsayıda olduğu gibi, farklı türdeki ifadelerin karşılaştırılmasına izin verilir. Ancak her veri türü çifti de doğrudan karşılaştırılamaz. Örneğin, bir sayı ile bir dizeyi karşılaştıramayız.
5.2.2 Tamsayılar ve Karakterlerin Karşılaştırılması Tamsayılar ve karakterleri karşılaştırdığımızda, doğrudan bellekteki ikili gösterimlerini karşılaştırıyoruz yani onların değerlerini karşılaştırırız. Örneğin, int türünde iki sayıyı karşılaştırıyorsak 4 baytlık kendi değerlerini karşılaştırmamız gerekiyor. Tamsayı ve karakter karşılaştırmaları için bir örnek aşağıda verilmiştir:
5.2.3 Nesne Referanslarının Karşılaştırılması .NET Framework herhangi bir değer içermeyen başvuru veri türleri vardır (değer türlerinin tersine). Bu türler değerin bulunduğu yığındaki bellek adresini içermektedir. Dizeler, diziler ve sınıflar bu gibi veri türlerindendir. Bazı değerlere bir işaretçi gibi davranırlar ve null değerini alabilirler, yani hiçbir değer. Referans türü değişkenleri karşılaştırırken, tuttukları adresleri karşılaştırırız, yani bellekte aynı konuma işaret edip etmediklerini kontrol ederiz, yani aynı nesneye.
İki nesne işaretçisi (referansı) aynı nesneye başvurabileceği gibi farklı nesnelere de işaret edebilir, yada bunlardan biri hiçbir yere işaret etmeyebilir (null değere sahip olabilir). Aşağıdaki örnekte yığında aynı değere (nesne) işaret eden iki değişken oluşturuyoruz.
string str = "beer";
string anotherStr = str;
Yukarıdaki kaynak kod çalıştırıldıktan sonra, str ve anotherStr değişkenlerinin ikisi de aynı nesneye işaret edecektir (“beer” değerini içeren string). Bu nesne yığında (yönetilen yığın) bir adreste yer almaktadır. Değişkenlerin aynı nesneye işaret edip etmediğini karşılaştırma operatörü (==) ile kontrol edebilirsiniz. Referans türlerinin çoğu için bu işleç nesnelerin içeriğini karşılaştırmaz, daha ziyade, bellekte aynı yere işaret edip etmediklerini denetler, yani aynı nesne olup olmadıklarını. Boyut karşılaştırmaları (<, >, <= ve >=) nesne tipi değişkenler için geçerli değildir. Aşağıdaki örnek nesne referanslarının karşılaştırılmasını göstermektedir:
Örnekte kullanılan dizeler (C# dilinde string anahtar sözcüğü tarafından tanımlanan System.String sınıfının örnekleri) referans türünde olduğu için değerleri yığında nesne olarak belirlenir. str ve thirdStr nesneleri eşit değere sahiptir ancak bellekte ayrı adreslerde bulunan farklı nesnelerdir. anotherStr değişkeni de ayrıca referans türündedir ve str adresini (referans) alır, yani varolan str nesnesine işaret eder. Bu nedenle str ve anotherStr değişkenlerinin karşılaştırılmasıyla bunların bir ve aynı nesne ve eşit oldukları anlaşılmaktadır. str ve thirdStr arasındaki karşılaştırmanın sonucu da eşitliktir çünkü == işleci dizeleri adreslerine göre değil, ancak değerlerine göre karşılaştırır (adresine göre karşılaştırma kuralı için çok kullanışlı bir istisna) Ancak biz daha sonra üç değişkeni nesnelere dönüştürürsek ve bunları karşılaştırırsak değerlerin bulunduğu yığın adreslerinin bir karşılaştırmasını alırız ve sonuç farklı olacaktır. Bu yukarıdaki örnek dizeleri karşılaştırırken == işlevinin özel bir davranışı olduğunu gösteriyor, ancak referans türlerinin geri kalanı için (diziler veya sınıflar gibi) adres ile karşılaştırma geçerlidir. String sınıfı ve dizeleri karşılaştırma hakkında daha fazlasını "Strings" ile ilgili bölümde öğreneceksiniz.
5.2.4 Mantıksal İşleçler C# dilindeki mantıksal işleçleri anımsayalım. Bunlar genellikle mantıksal (Boole) ifadeleri oluşturmak için kullanılır. Mantıksal operatörler şunlardır: &&, ||, ! ve ^.
5.2.4.1 Mantıksal İşleçler && ve || Mantıksal işleçler && (mantıksal VE) ve || (mantıksal VEYA) yalnızca Boole ifadeler (bool türü değerler) üzerinde kullanılır. && işleci ile iki ifadeyi karşılaştırma sonucunun true (doğru) olması için her iki işlenen değerinin de true olması gerekir. Örneğin:
bool result = (2 < 3) && (3 < 4);
Bu ifade, "true"dur, çünkü işlenenlerin her ikisi: (2 < 3) ve (3 < 4) "true"dur. && mantıksal işlecine kısa-devre de denir, çünkü gereksiz hesaplamalarla zaman kaybetmez. Bir ifadenin sol kısmını değerlendirir (birinci işlenen) ve sonucu false ise ikinci işleneni değerlendirmek için zaman kaybetmez – ilk işlenen "true" değilken son sonucun "true" olması mümkün değildir. Bu nedenle, aynı zamanda kısa-devre mantıksal işleci "ve" olarak adlandırılır. Benzer şekilde, || işleci iki işlenenden en az biri "true" değere sahip olursa "true" döndürür. Örnek:
bool result = (2 < 3) || (1 == 2);
İlk işlenen "true" olduğu için bu örnek, "true"dur. Tıpkı && işleci gibi, hesaplama hızlı yapılır – ilk işlenen "true" ise ikincisi hiç hesaplanmamıştır, çünkü sonuç belli olmuştur. Aynı zamanda kısa-devre mantıksal "veya" işleci denir.
5.2.4.2 Mantıksal İşleçler & ve | Karşılaştırma için & ve | işleçleri sırasıyla && ve || işleçlerine benzerdir. Fark iki işlenenin birbiri ardına hesaplanmış olması gerçeğinde yatmaktadır, sonucun önceden bilinmesine rağmen hesaplama sonuna kadar devam eder. bu yüzden bu karşılaştırma işleçleri tam-devre mantıksal işleçler olarak da bilinir ve çok nadiren kullanılır. Örneğin, iki işlenen & ile karşılaştırıldığında ve ilki "false" olarak değerlendirildiyse, ikinci işlenenin hesaplaması hâlâ yürütülür. Sonuç açıkça "false" olur. Aynı şekilde, iki işlenen | ile karşılaştırıldığında ve ilki "true" olarak değerlendirildiyse, hâlâ ikinci işleneni değerlendiririz ve nihai sonuç yine "true" olur. Mantıksal işleçler & ve | bitsel işleçler & ve | ile karıştırılmamalıdır. Aynı şekilde yazılıyor olmalarına rağmen farklı argümanlar (Boole veya tamsayı ifadeler) alırlar ve farklı bir sonuç (bool veya tamsayı) döndürürler ve etkileri özdeş değildir.
5.2.4.3 Mantıksal İşleçler ^ ve ! ^ işleci exclusive OR (XOR) olarak da bilinir, tam-devre işleçlerine aittir, çünkü her iki işlenen birbiri ardına hesaplanır. İşlenenlerin tam olarak biri doğruysa, fakat ikisi aynı anda değil, işlecin uygulanmasının sonucu true olur. Aksi takdirde sonuç false olur. İşte bir örnek:
Örnekteki ifade false olarak değerlendirilir, çünkü her iki işlenen: (2 < 3) ve (4 > 3) doğrudur.
! işleci bağlı olduğu Boole ifadesinin tersine değerini verir. Örnek:
bool value = !(7 == 5); // True
Console.WriteLine(value);
Yukarıdaki ifade “(7 == 5) ifadesinin gerçekliğinin tersi" olarak okunabilir. Sonucu (False tersi) True olur. true değerini yazdırırken konsolda "True" görüntülenir (ilk harfi büyük). Bu hata .NET Framework’te çalışan VB.NET dilinden ileri gelmektedir.
5.3 Koşullu Deyimler "if" ve "if-else" İfadelerin nasıl karşılaştırıldığını inceledikten sonra, programlama mantığını uygulamamızı sağlayan koşullu deyimler ile konumuzu işlemeye devam edeceğiz. Koşullu deyimler olan if ve if-else koşullu kontrol deyimleridir. Program bunlar tarafından deyimin çalıştırılması sırasında kontrol edilen tanımlı bir koşula dayalı olarak farklı davranış gösterebilir.
5.3.1 Koşullu Deyim "if" if koşullu deyimini oluşturan ana biçim aşağıdaki gibidir:
if (Boole ifadesi)
{
Koşullu deyimin gövdesi;
}
Burada if-deyimi, Boole ifadesi ve koşullu deyimin gövdesi yer almaktadır. Boole ifadesi bir Boole değişken veya Boole mantıksal ifadesi olabilir. Boole ifadeleri tamsayı olamaz (C ve C ++ gibi diğer programlama dilleri aksine). Deyimin gövdesi kıvırcık parantezler {} arasında kilitli kalan parçadır. Bir veya daha fazla komuttan (deyimden) oluşabilir. Birkaç komut olduğunda, karmaşık blok işlecinden söz ederiz, yani birbiri ardınca kıvırcık parantezler içerisinde dizilen deyimlerden. if anahtar sözcüğünü takip eden parantez içindeki ifadenin true veya false Boole değerini döndürmesi gerekir. İfade true değerini hesapladığı takdirde, koşullu ifadenin gövdesi çalıştırılır. Sonuç false ise, o zaman gövde içindeki komutlar atlanacaktır.
5.3.1.1 Koşullu Deyim "if" – Örnek ifkoşullu deyimini kullanan bir örneğe göz atalım:
static void Main()
{
Console.WriteLine("Enter two numbers.");
Console.Write("Enter first number: ");
int firstNumber = int.Parse(Console.ReadLine());
Console.Write("Enter second number: ");
int secondNumber = int.Parse(Console.ReadLine());
int biggerNumber = firstNumber;
if (secondNumber > firstNumber)
{
biggerNumber = secondNumber;
}
Console.WriteLine("The bigger number is: {0}", biggerNumber);
}
Örneği başlatırsanız ve 4 ve 5 sayılarını girerseniz, aşağıdaki sonucu alırsınız: