Bir Dizgeyi Dizgeciklere Ayırma
Önceki V. Oylum - Diziler ve Dizgeler Sonraki
Bir Dizgeyi Dizgeciklere Ayırma
Hemen tüm uygulamalarda, bir komut dizgesini dizgeciklere ayırmak gibi bazı basit ayrıştırma işlemlerine ihtiyaç duyulur. Bunu string.h başlık dosyasında bildirilmiş olan strtok işlevi ile yapabilirsiniz.
char *strtok
(char *restrict       yeni-dizge,
 const char *restrict ayraçlar)
işlev
Bir dizge strtok işlevini peşpeşe çağırarak dizgeciklerine bölünebilir.
Bölünecek dizge ilk çağrıda yeni-dizge argümanı ile işleve aktarılır. strtok işlevi bunu bazı dahili durum bilgilerini ayarlamakta kullanır. Sonraki çağrılarda, yeni-dizge argümanında bir boş gösterici aktarılması aynı dizgeden başka dizgeciklerin alınacağını belirtir. yeni-dizge argümanında boş gösterici olmayan bir gösterici belirterek yapılan her strtok çağrısı durum bilgilerini yeniden ilklendirir. Hiçbir kütüphane işlevinin sizin haberiniz olmadan (bu dahili durum bilgisini karıştıran) strtok çağrısı yapmayacağı garanti edilmiştir.
ayraçlar argümanı çıkarılacak dizgecikleri belirlemede kullanılan ayraçlardan oluşan bir dizgedir. Bu ayraçlardan birine rastlandığında bu karakter bir boş karakterle değiştirilir ve dizgenin başlangıcı yeni-dizge argümanında döndürülür. Dizgecikler daima dizgeciğin sonunda bir ayracın varlığına göre ayrılır.
Sonraki strtok çağrılarında arama önceki dizgeciği sonlandıran boş karakterden sonraki karakterden başlar. Sonraki strtok çağrılarında hep aynı ayraçlar dizgesini kullanmak zorunluluğu yoktur.
yeni-dizge dizgesinin sonuna gelindiğinde ya da kalan dizge sadece ayraç karakterlerinden oluşuyorsa işlev boş gösterici ile döner.
Burada karakter bayt anlamındadır. Çok baytlı karakter kodlaması kullanılan dizgelerde bir karakter birden fazla bayttan oluştuğundan bu işlevde her bayt ayrı ayrı değerlendirilir. Bu işlev yerele bağımlı değildir.
wchar_t *wcstok
(wchar_t    *yeni-dizge,
 const char *ayraçlar)
işlev
Bir dizge wcstok işlevini peşpeşe çağırarak dizgeciklerine bölünebilir.
Bölünecek dizge ilk çağrıda yeni-dizge argümanı ile işleve aktarılır. wcstok işlevi bunu bazı dahili durum bilgilerini ayarlamakta kullanır. Sonraki çağrılarda, yeni-dizge argümanında bir boş gösterici aktarılması aynı dizgeden başka dizgeciklerin alınacağını belirtir. yeni-dizge argümanında boş gösterici olmayan bir gösterici belirterek yapılan her wcstok çağrısı durum bilgilerini yeniden ilklendirir. Hiçbir kütüphane işlevinin sizin haberiniz olmadan (bu dahili durum bilgisini karıştıran) wcstok çağrısı yapmayacağı garanti edilmiştir.
ayraçlar argümanı çıkarılacak geniş karakterli dizgecikleri belirlemede kullanılan ayraçlardan oluşan bir geniş karakterli dizgedir. Bu ayraçlardan birine rastlandığında bu geniş karakter bir boş karakterle değiştirilir ve dizgenin başlangıcı yeni-dizge argümanında döndürülür. Dizgecikler daima dizgeciğin sonunda bir ayracın varlığına göre ayrılır.
Sonraki wcstok çağrılarında arama önceki dizgeciği sonlandıran boş karakterden sonraki geniş karakterden başlar. Sonraki wcstok çağrılarında hep aynı ayraçlar dizgesini kullanmak zorunluluğu yoktur.
yeni-dizge geniş karakterli dizgesinin sonuna gelindiğinde ya da kalan geniş karakterli dizge sadece ayraç karakterlerinden oluşuyorsa işlev boş gösterici ile döner.
Uyarı
strtok ve wcstok işlevleri ayrıştırma sırasında dizgeyi değiştirdiğinden, strtok/wcstok çağrısından önce dizgeyi daima geçici bir tampona kaydetmelisiniz (Bkz. Kopyalama ve Birleştirme). strtok veya wcstok işlevinin yazılımınızın başka bir parçasından gelen bir dizgeyi değiştirmesine izin verirseniz, strtok veya wcstok çağrısından sonra dizge değişmiş olacağından dizgenin başka amaçlar için kullanılması gerektiğinde umduğunuz değerde olmayacağından sorunlarla karşılaşabilirsiniz.
İşleme soktuğunuz dizge bir sabit olduğu takdirde, strtok veya wcstok işlevi onu değiştirmeye kalktığında yazılımınız salt-okunur belleğe yazacağından bir ölümcül hata alacaktır Bkz. Yazılım Hatalarının Sinyalleri. strtok veya wcstok işlevinin yaptığı işlemin dizgeyi değiştirmeyeceğini (mesela sadece bir dizgecik vardır) düşünseniz bile dizge değiştirilebilir (GNU libc değiştirecektir).
Bu, bir genel prensibin özel durumudur: Eğer bir yazılım parçası belli bir veri yapısını güncelleme ile görevlendirilmemişse sözkonusu veri yapısının bu yazılım tarafından geçici olarak güncellenmesi hatalara yol açabilir.
strtok ve wcstok işlevleri evresel değildir. Evreselliğin nerede ve niçin önemli olduğu Sinyal İşleme ve Evresel Olmayan İşlevler bölümünde açıklanmıştır.
strtok işlevinin kullanımına bir örnek:
#include <string.h>
#include <stddef.h>

…

const char
  dizge[] = "noktalama isaretleri -- ve bosluklarla ayrilmis kelimeler!";
const char ayraclar[] = " .,;:!-";
char *dizgecik, *kopya;

…

kopya = strdupa (dizge);             /* Yazılabilir kopya.  */
dizgecik = strtok (kopya, ayraclar); /* dizgecik => "noktalama" */
dizgecik = strtok (NULL, ayraclar);  /* dizgecik => "isaretleri" */
dizgecik = strtok (NULL, ayraclar);  /* dizgecik => "ve" */
dizgecik = strtok (NULL, ayraclar);  /* dizgecik => "bosluklarla" */
dizgecik = strtok (NULL, ayraclar);  /* dizgecik => "ayrilmis" */
dizgecik = strtok (NULL, ayraclar);  /* dizgecik => "kelimeler" */
dizgecik = strtok (NULL, ayraclar);  /* dizgecik => NULL */
GNU C kütüphanesi bir dizgeyi dizgeciklerine bölmek için, tek katılışlı olmanın sınırlamalarını aşan iki işlev daha içerir. Bu işlevler sadece çok karakterli karakter dizgeleri için kullanılabilir.
char *strtok_r
(char       *yeni-dizge,
 const char *ayraçlar,
 char      **sonraki)
işlev
Bu işlev, strtok gibi, ardışık olarak çağrılarak bir dizgeyi dizgeciklerine ayırmakta kullanılır. Farkı, sonraki dizgecik hakkındaki bilgilerin, bir dizge göstericisine gösterici olan sonraki argümanı ile gösterilen alanda saklanmasıdır. İşlevin, yeni-dizge argümanının boş gösterici ile ve çağrılar arasında sonraki argümanının değişmeden bırakılarak çağrılması, çok katılışlılığı engellemeksizin işlemin yapılmasını sağlar.
Bu işlev POSIX.1 içinde tanımlıdır ve çok evreliliği destekleyen çoğu sistemde bulunur.
char *strsep
(char      **sonraki,
 const char *ayraç)
işlev
Bu işlev, strtok_r işlevinden yeni-dizge argümanının yerini sonraki argümanını alması dışında strtok_r işlevine benzer. Taşıyıcı göstericinin ilklendirilmesi yazılımcı tarafından yapılır. Ardışık çağrılarla ayraç ile ayrılan dizgeciğin adresi ile dönerken, sonraki dizgeciğin başlangıcını gösteren sonraki argümanını günceller.
strsep ile strtok_r arasındaki bir diğer fark da, eğer girdi dizgesi içinde ayraç karakterlerinden biri birden fazla içeriliyorsa, her ayraç karakteri çifti için bir boş dizge döndürmesidir. Bu demektir ki, bir yazılım normalde işlevi çalıştırmadan önce bir boş dizge döndürüp döndürmediğini sınamalıdır.
Bu işlev 4.3 BSD içinde tanımlıdır ve genişçe bir kullanım alanı vardır.
Yukarıdaki örneği strsep için uyarlarsak:
#include <string.h>
#include <stddef.h>

…

const char
  dizge[] = "noktalama isaretleri -- ve bosluklarla ayrilmis kelimeler!";
const char ayraclar[] = " .,;:!-";
char *dizgecik, *kopya;

…

kopya = strdupa (dizge);
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "noktalama" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "isaretleri" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "isaretleri" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "ve" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "bosluklarla" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "ayrilmis" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "kelimeler" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => "" */
dizgecik = strsep (&kopya, ayraclar);    /* dizgecik => NULL */
char *basename
(const char *dosyaismi)
işlev
basename işlevinin GNU sürümü, dosyaismi ile belirtilen dosya yolunun son elemanı ile döner. dosyaismi argümanını içerdiği bölü çizgileri bakımından değiştirmediğinden kullanımı tercih edilir. İşlevi prototipi string.h dosyasında bulunabilir. Eğer libgen.h dosyası da içerilmişse bu işlevin XPG sürümü ile değiştirileceğini aklınızdan çıkarmayın.
GNU basename işlevinin kullanım örneği:
#include <string.h>

int
main (int argc, char *argv[])
{
  char *prog = basename (argv[0]);

  if (argc < 2)
    {
      fprintf (stderr, "Kullanimi: %s <arg>\n", prog);
      exit (1);
    }

  …
}
Taşınabilirlik Bilgisi
Bu işlev, farklı sistemlerde farklı sonuçlar üretebilir.
char *basename
(char *dosyayolu)
işlev
basename işlevinin XPG sürümüdür ve ruhen GNU sürümüne benzer. Fakat, dosyayolu içindeki '/' karakterleri silinerek değişikliğe uğratılır. Eğer argüman sadece '/' karakterinden oluşuyorsa '/' karakteri döner. Ayrıca, NULL ise ya da bir boş dizge ise "." döner. İşlevin prototipi libgen.h dosyasında bulunabilir.
XPG basename kullanım örneği:
#include <libgen.h>

int
main (int argc, char *argv[])
{
  char *prog;
  char *path = strdupa (argv[0]);

  prog = basename (path);

  if (argc < 2)
    {
      fprintf (stderr, "Kullanimi: %s <arg>\n", prog);
      exit (1);
    }

  …

}
char *dirname
(char *dosyayolu)
işlev
dirname işlevi, basename işlevinin XPG sürümünün tümleyenidir. dosyayolu ile belrtilen dosyayı içeren dizin ile döner. Argümanın değeri NULL ise veya bir boş dizge ise ya da hiç '/' karakteri içermiyorsa, "." döner. İşlevin prototipi libgen.h dosyasında bulunabilir.
Önceki Üst Ana Başlık Sonraki
Uyumluluk için Varolan Dizge Arama İşlevleri Başlangıç strfry
Bir Linux Kitaplığı Sayfası