Değişkin Çıktı İşlevleri
Önceki Biçimli Çıktı Sonraki
Değişkin Çıktı İşlevleri
Yerleşik biçimli çıktı işlevleri olarak printf oluşumunu kullanarak kendi değişkin printf benzeri işlevlerinizi tanımlayabilmeniz için vprintf işlevi ve arkadaşları oluşturulmuştur.
Bu tür işlevleri tanımlamanın en doğal yolu, "printf işlevini çağır ve bu şablonla birlikte ilk 5 argümandan sonra benim argümanlarımı aktar" diyecek bir dil yapısı kullanmak olurdu. Fakat C'de bunu yapmanın bir yolu yoktur. Ayrıca üçüncü düzey C dilinde işlevinizin kaç argüman aldığını söyleyecek bir yol olmadığından, bir yol üretmek de zor olurdu.
Bu yöntemle mümkün olmadığından "ilk 5 argümandan sonra benim argümanlarımı aktar" diyebileceğiniz bir va_list'i aktaracağınız bir seri işlev, vprintf serisini ürettik.
Gerçek bir işlev yerine bir makro tanımlamak yeterli olduğundan, GNU C derleyicisi bunu makrolarla çok daha kolay yapacak bir yol sağlar. Örneğin:
#define myprintf(a, b, c, d, e, rest...) \
         printf (mytemplate , ## rest)
Değişken sayıda argümanlı makrolar hakkında ayrıntılı bilgi edinmek için GCC info'sundaki "Macros with Variable Numbers of Arguments" (Değişken sayıda argümanlı makrolar) bölümüne bakınız. Bu yol sadece makrolara ayrılmıştır, gerçek işlevlere uygulanmaz.
vprintf veya bu bölümde listelenmiş diğer işlevleri çağırmadan önce değişken sayıdaki argümanı ilklendirmek için bir va_start çağrısı (Değişkin İşlevler) yapmalısınız. Sonra da kendinizin elde etmek istediğiniz argümanları almak için va_arg çağrıları yapmalısınız.
va_list göstericinize seçtiğiniz ilk argümanı gösterdikten sonra bir vprintf çağrısı yapmaya hazırsınız demektir. İşlevinizle aktardığınız bu argüman ve artbileşen argümanlar ile belirttiğiniz şablon dizgesi vprintf işlevi tarafından kullanılacaktır.
Diğer sistemlerde vprintf çağrısından sonra va_list göstericisi geçersiz duruma gelebilir ve vprintf çağrısından sonra va_arg işlevini kullanamayabilirsiniz. Bu durumda bir va_end çağrısından sonra va_start ile göstericiyi yeniden almalısınız. vprintf işlevi işlevinizin argüman listesini ortadan kaldırmaz.
GNU C böyle sınırlamalara sahip değildir. va_list göstericisini vprintf çağrısına aktardıktan sonra bu göstericiyi kullanarak argümanları almaya devam edebilirsiniz ve va_end çağrısı da hiçbir işlem yapmaz. (vprintf çağrısından sonra yaptığınız va_arg çağrıları ile alınan argümanlar vprintf çağrısındaki argümanlarla aynıdır.)
Bu işlevlerin prototipleri stdio.h başlık dosyasında bildirilmiştir.
int vprintf
(const char *şablon,
 va_list     arglist-gstr)
işlev
Bu işlev değişken sayıdaki argümanlarını doğrudan almak yerine arglist-gstr argüman listesi göstericisinden alması dışında printf ile aynıdır.
int vwprintf
(const wchar_t *şablon,
 va_list        arglist-gstr)
işlev
Bu işlev değişken sayıdaki argümanlarını doğrudan almak yerine arglist-gstr argüman listesi göstericisinden alması dışında wprintf ile aynıdır.
int vfprintf
(FILE       *akım,
 const char *şablon,
 va_list     arglist-gstr)
işlev
Bu işlev değişken sayıdaki argümanlarını doğrudan almak yerine arglist-gstr argüman listesi göstericisinden alması dışında vprintf ile aynıdır.
int vfwprintf
(FILE          *akım,
 const wchar_t *şablon,
 va_list        arglist-gstr)
işlev
Bu işlev değişken sayıdaki argümanlarını doğrudan almak yerine arglist-gstr argüman listesi göstericisinden alması dışında vwprintf ile aynıdır.
int vsprintf
(char       *s,
 const char *şablon,
 va_list     arglist-gstr)
işlev
Bu işlev değişken sayıdaki argümanlarını doğrudan almak yerine arglist-gstr argüman listesi göstericisinden alması dışında sprintf ile aynıdır.
int vswprintf
(wchar_t       *s,
 size_t         boyut,
 const wchar_t *şablon,
 va_list        arglist-gstr)
işlev
Bu işlev değişken sayıdaki argümanlarını doğrudan almak yerine arglist-gstr argüman listesi göstericisinden alması dışında swrintf ile aynıdır.
int vsnprintf
(char       *s,
 size_t      boyut,
 const char *şablon,
 va_list     arglist-gstr)
işlev
Bu işlev değişken sayıdaki argümanlarını doğrudan almak yerine arglist-gstr argüman listesi göstericisinden alması dışında snprintf ile aynıdır.
int vasprintf
(char      **gstr,
 const char *şablon,
 va_list     arglist-gstr)
işlev
Bu işlev değişken sayıdaki argümanlarını doğrudan almak yerine arglist-gstr argüman listesi göstericisinden alması dışında vasprintf ile aynıdır.
int obstack_vprintf
(struct obstack *yığınak,
 const char     *şablon,
 va_list         arglist-gstr)
işlev
Bu işlev değişken sayıdaki argümanlarını doğrudan almak yerine arglist-gstr argüman listesi göstericisinden alması dışında obstack_vprintf ile aynıdır.
Aşağıda vfprintf kullanılan bir örnek vardır. Örnekteki işlev yazılımın ismi ile önceleyerek standart hataya bir ileti basmaktadır. (program_invocation_short_name değişkeninin açıklamaları için Hata İletileri bölümüne bakınız.)
#include <stdio.h>
#include <stdarg.h>

void
eprintf (const char *sablon, ...)
{
  va_list ap;
  extern char *program_invocation_short_name;

  fprintf (stderr, "%s: ", program_invocation_short_name);
  va_start (ap, sablon);
  vfprintf (stderr, sablon, ap);
  va_end (ap);
}
     
eprintf işlevi şöyle çağrılabilir:
eprintf ("`%s' diye bir dosya yok\n", filename);
GNU C'de printf tarzı biçim dizgesi kullanan bir işlevi derleyiciye bildirebileceğiniz özel bir yapı vardır. Bu yapı kullanıldığında işlevin her çağrısı için kullanılan argümanların türleri ve sayısı denetlenir ve biçim dizgesiyle eşleşmeyenler için sizi uyarır. Örneğin, bu yapıyı eprintf için şöyle kullanabilirsiniz:
void eprintf (const char *sablon, ...)
        __attribute__ ((format (printf, 1, 2)));
Bu kod parçası derleyiciye eprintf işlevinin ilk argümanının printf biçim dizgesi olarak, biçim dizgesini oluşturan diğer argümanların başlangıcının ikinci argüman olarak kullanıldığını söyler. İşlev özniteliklerinin bildirilmesi ile ilgili ayrıntılı bilgi edinmek için GCC kılavuzunun (info) "Declaring Attributes of Functions" (İşlevlerin Özniteliklerinin Bildirilmesi) bölümüne bakınız.
Önceki Üst Ana Başlık Sonraki
Biçimli Çıktıyı Özdevimli Ayırma Başlangıç Bir Şablon Dizgesinin Çözümlenmesi
Bir Linux Kitaplığı Sayfası