Standart C Programlama Dili


1.7. Basit Girdi/Çıktı

Girdi ve çıktı deyimleri gerçekte C dilinin bir parçası değildir. Yani, diğer programlama dillerinin tersine, C dilinin içine konmuş girdi/çıktı deyimleri yoktur. Girdi/çıktı işlemleri, her zaman, fonksiyonlar çağrılarak yapılır. Tabii ki, girdi/çıktı yapmak için kullanılan fonksiyonların programcı tarafından yazılmasına gerek yoktur. Hemen hemen bütün C ortamlarında girdi/çıktı fonksiyonları içeren standart kütüphaneler bulunmaktadır. Bu kütüphanelerde tanımlanmış bulunan fonksiyonlar (ile alabilecekleri argümanlar) ve ilgili birtakım değişkenlerin bildirisi ise bir başlık dosyasına konur. stdio.h böyle bir başlık dosyasıdır ve herhangi bir standart girdi/çıktı fonksiyonu çağrılmadan veya değişkenleri kullanılmadan önce

#include <stdio.h>

yazılarak kaynak programın içine kopyalanması gerekir.

Kullanıcının girdi/çıktı yapması için, üç girdi/çıktı ara dosyasının tanımı önceden yapılmıştır. Bunlar şunlardır:

stdinstandart girdi
stdoutstandart çıktı
stderrstandart hata çıktısı

ve normal olarak kullanıcının klavye ve ekranına bağlanmıştır.

Programcının basit girdi/çıktı işlemleri yapması için, sadece gerekli olan printf, scanf, getchar, putchar, _getch ve _getche fonksiyonları bu kısımda anlatılacaktır. Diğer girdi/çıktı fonksiyonları için girdi/çıktı ile ilgili bölüme bakınız.

printf(kontrol_karakter_dizisi, argüman_listesiopt) Fonksiyonu

Bu fonksiyon stdout’a yapılacak biçimli çıktı içindir. Kontrol_karakter_dizisi, argüman_listesindeki argümanların değerlerinin çıktısını denetleyen sıfır veya daha fazla dönüşüm tanımlamaları sağlar. Argüman_listesi virgüllerle ayrılmış argümanlardan oluşur ve bulunması zorunlu değildir.

En basit dönüşüm tanımlaması şu şekildedir:

%z

Burada z’nin yerine aşağıdaki dönüşüm karakterlerinden biri gelmelidir:

Dönüşüm karakteri Çıktı
c işaretsiz bir karakter
s karakter dizisi (karakter göstergesi)
d veya i işaretli bir ondalık tamsayı
u işaretsiz bir ondalık tamsayı
x, X işaretsiz bir onaltılı tamsayı
o işaretsiz bir sekizli tamsayı
f double
e, E e veya E gösteriminde double
g, G e (E) veya f’nin en kısası
p bir göstergenin değeri
n şimdiye kadar yazılmış olan karakterlerin sayısı

Genelde, bir dönüşüm tanımlaması şu şekildedir:

%f0w.plz

Burada f isteğe bağlı olarak aşağıdaki bayraklardan biridir:

Bayrak Anlamı
- çıktı alanında sola yanaştır
+ öne bir işaret koy
# kayan noktalı sayılar için mutlaka nokta konmasını sağla; sekizli için öne 0, onaltılı için öne 0x (0X) koy
boşluk karakteri eğer işaret yoksa bir boşluk koy

İsteğe bağlı olan 0, sayının solunu sıfırla doldurmak içindir. İsteğe bağlı olan w sayısı, çıktı değerini alacak olan çıktı alanının genişliğini belirtir. İsteğe bağlı olan p sayısı, kayan noktalı bir sayı için kesir kısmındaki rakamların sayısını, bir karakter dizisi için yazılacak en fazla karakter sayısını veya bir tamsayı için yazılacak en az rakam sayısını gösterir. İsteğe bağlı olan l ise argümanın short int yani kısa (h), long int yani uzun (l), long long int yani çok uzun (ll) bir tamsayı veya long double yani uzun (L) bir double olduğunu gösterir.

float için bir dönüşüm tanımlaması olmadığına dikkat edin; herhangi bir float ifadeyi bir kalıp kullanarak double’a dönüştürün. w ve p’nin yerine konulacak bir *, genişliğin argüman_listesindeki bir int argümandan alınacağını gösterir. Normalde, değerler çıktı alanlarında sağa yanaştırılırlar.

İşte bazı örnekler. c’nin int, toplam’ın da double olduğunu varsayın. Yeni satır karakterlerine dikkat edin.

printf("Merhaba\n");
printf("%s\n", "Merhaba");    /* yukaridakiyle ayni cikti */
printf("\nSayi=%d adet", c);  /* c'nin degeri gereken genis- */
                              /* likte bir tamsayi olarak yazilir */
printf("\nSayi=%4d adet", c);
        /* yukaridakiyle ayni, ancak alan genisligi en az 4 */
printf("\nToplam=%5.2f", toplam);
printf("\nToplam=%*.*f", 5, 2, toplam);
        /* toplam'in degeri dd.dd biciminde yazilir */
printf("\nToplam=%5.2f Sayi=%4d", toplam, c);

Eğer %’den sonraki karakter geçerli bir karakter değilse, sonucun ne olacağı belirsizdir; %% tek bir yüzde işareti basar. printf fonksiyonu hakkında daha fazla bilgi için, ilgili C derleyicisinin girdi/çıktı kütüphane fonksiyonları el kitabına veya çevrimiçi yardım kolaylıklarına bakılması önerilir.

scanf(kontrol_karakter_dizisi, argüman_listesiopt) Fonksiyonu

Bu fonksiyon stdin’den biçimli girdi yapmak içindir. Kontrol_karakter_dizisi, argüman_listesindeki argümanlara verilecek değerleri kontrol eden sıfır veya daha fazla dönüşüm tanımlamaları sağlar. Kontrol_karakter_dizisindeki dönüşüm karakterleri dışındaki karakterlerin, girdi akımında karşılık gelen karakterlerle aynı olması beklenir (girdi akımındaki boşluk ve tab karakterleri atlanır). Argüman_listesi girdi değerleri için hedef olan değişkenlerin adreslerinin, birbirinden virgülle ayrılarak, yazılmasından oluşur. Yapılmış olan başarılı dönüşümlerin sayısı, fonksiyonun değeri olarak geri döndürülür.

Dönüşüm tanımlamaları şu şekildedir:

%*wlz

Burada * değerin argümana atanmasını engeller, w en büyük alan genişliğini belirtir, l ise argümanın büyüklüğünü gösterir. Üçü de isteğe bağlıdır. z dönüşüm karakteri genelde printf’teki gibidir. Girdi akımında, bir alan, beyaz (boşluk, tab, yeni satır vs) olmayan bir karakterle başlayıp, ilk gelen beyaz karakterle veya belirtilen alan uzunluğu sonunda biter.

İşte bazı örnekler. c1, c2’nin char, i’nin int, y’nin float, d’nin double ve s’nin char dizisi olduğunu varsayın. %lf bir sayının okunmasını ve double olarak depolanmasını sağlar. long double için %Lf kullanın. & işlecinin, fonksiyona değişkenin değerinin değil de adresinin iletilmesi için kullanıldığına dikkat edin. Bu işleç Bölüm 3’te anlatılacaktır.

scanf("%d", &i);
scanf("%4d", &i);
scanf("%c%c%*3s%d%f%lf", &c1, &c2, &i, &y, &d);
scanf("%[^.].", s);
scanf("%[ABC]", s);

Son iki örneğin ilki, (beyaz boşluk karakterlerinden biriyle değil de) bir nokta ile sonlandırılmış bir karakter dizisinin okunarak noktanın atlanmasını sağlar. Son örnekte, sadece A, B veya C karakterlerini içeren bir karakter dizisi okunmaktadır. scanf fonksiyonunun kullanımı hakkında daha fazla bilgi için, derleyicinizin elkitaplarına veya çevrimiçi yardım kolaylıklarına başvurunuz.

getchar() Ve putchar() Fonksiyonları

Bu fonksiyonlar stdin’den veya stdout’a bir karakterin girilmesini veya çıktısının yapılmasını sağlarlar. Tipik bir kullanım şöyledir. c’nin char veya int olduğunu farzedin.

c = getchar();
putchar(c);

Eğer klavyeden girilen bir karakter dizisi arka arkaya getchar fonksiyonunun çağrılmasıyla okunursa, getchar()’ın vereceği son karakter satır ilerletme karakteri ('\n') olacaktır, çünkü (özellikle Microsoft DOS ve Windows ortamlarında kullanılan) satırbaşı karakteri ('\r') standart girdi/çıktı yordamları tarafından elenmektedir. Aynı şekilde, putchar() kullanıldığında, satır sonuna '\n' yazılması yeterlidir; '\r' karakteri otomatik olarak '\n'’nin önüne eklenecektir.

_getch() Ve _getche() Fonksiyonları

Standart olmayan bu fonksiyonlar, klavyedeki bir tuşa yapılan tek bir vuruştan ortaya çıkan karakteri verirler. Yani programın bilgi alabilmesi için, getchar() gibi, satırın enter’la bitirilmesini beklemezler. _getche()’de girilen karakter ekrana yansıtılır, _getch()’de bu olmaz. Not: Bu fonksiyonlar standart olmadıkları için, isimlerinin önünde altçizgi (_) karakteri bulunmaktadır; ancak bazı sistemlerde, örneğin Microsoft C derleyicisinin eski uyarlamalarında, altçizgi karakteri olmadan kullanılmaları gerekebilir. Verilen örnek programlarda bunu dikkate alarak, kendi sisteminiz için gerekli düzenlemeleri yapabilirsiniz.

Girdide Dosya Sonu Kontrolü

stdio.h başlık dosyasında #define ile tanımlanmış bulunan EOF ismi dosya sonunu kontrol etmek için kullanılabilir. Microsoft ortamlarında, dosya sonu ASCII ondalık kodu 26 olan control+z (klavyedeki control tuşu basılı iken z’ye basılarak oluşturulur) karakterinin alınması şeklinde tanımlanmıştır. Aynı işlem unix ve unix-benzeri ortamlarda control+d tuşu ile yapılır. Ancak C kütüphanesindeki standart bir fonksiyon tarafından döndürülen dosya sonu işareti EOF’tur. if deyiminin henüz anlatılmamasına rağmen, aşağıdaki örnek stdin’den dosya sonunun nasıl anlaşılabileceğini gösterir. Dikkat: EOF normal bir karakter değerinin dışında bir değer ile ifade edildiği için, c’nin tipi en azından int olmalıdır.

c = getchar();
if (c == EOF) {  /* eger dosya sonu ise */
  ...
  dosya sonu işlemleri yapan deyimler
  ...
}