Kopyalama ve Birleştirme
Önceki V. Oylum - Diziler ve Dizgeler Sonraki
Kopyalama ve Birleştirme
Bu kısımda açıklanan işlevleri dizi ve dizgelerin içeriğini kopyalamakta veya bir dizinin içeriğini diğerine eklemekte kullanabilirsiniz. str ve mem işlevleri string.h başlık dosyasında, wstr ve wmem işlevleri ise wchar.h başlık dosyasında bildirilmiştir. Bu kısımdaki işlevlerin argümanlarının sırası hedef, kaynak şeklindedir ve işlevler daima hedef dizinin adresi ile dönerler.
Bu işlevlerin çoğu kaynak ve hedef dizilerinin birbirinin üstüne binmesi durumunda düzgün çalışmaz. Örneğin, kaynak dizisinin sonu, hedef dizisinin başlangıcını aşarsa, kaynak dizisinin başlangıcı, kendi sonunun üzerine yazılır ve bu durumda kaynak dizisini sonlandıran boş karakter kaybolur. Sonlandırıcı boş karakter olmadığından kopyalama işlemi tüm belleğin ayrılmasına kadar gidebilir.
Dizilerin kopyalanmasında birbirinin üzerine binmesi sorunu olan tüm işlevler bu kılavuzda açıkça belirtilmiştir. Bu kısımdaki işlevlere ek olarak sprintf (Biçimli Çıktı İşlevleri) ve scanf (Biçimli Girdi İşlevleri) gibi başka işlevler de vardır.
void *memcpy
(void *restrict       hedef,
 const void *restrict kaynak,
 size_t               boyut)
işlev
memcpy işlevi boyut baytı kaynak adresinden başlayan nesneden hedef adresinden başlayan nesneye kopyalar. Bu işlevde kaynak dizisinin hedef dizisinin üzerine binmesi durumundaki davranışı tanımsızdır; üstüste binme olasılığı varsa memmove kullanın.
İşlev, hedef'in değeri ile döner.
Bu örnekte bir dizinin içeriğini kopyalamak için memcpy işlevinin nasıl kullanılacağı gösterilmiştir:
struct foo *eskidizi, *yenidizi;
int diziboyu;
…
memcpy (yeni, eski, diziboyu * sizeof (struct foo));
wchar_t *wmemcpy
(wchar_t *restrict       hedef-geniş,
 const wchar_t *restrict kaynak-geniş,
 size_t                  boyut)
işlev
wmemcpy işlevi boyut geniş karakteri kaynak-geniş adresinden başlayan nesneden hedef-geniş adresinden başlayan nesneye kopyalar. Bu işlevde kaynak-geniş dizisinin hedef-geniş dizisinin üzerine binmesi durumundaki davranışı tanımsızdır; üstüste binme olasılığı varsa wmemmove kullanın.
Aşağıda wmemcpy işlevinin olası bir gerçeklemesi vardır. Başka olası eniyilemeleri de vardır.
wchar_t *
wmemcpy (wchar_t *restrict hedefg, const wchar_t *restrict kaynakg,
         size_t boyut)
{
  return (wchar_t *) memcpy (hedefg, kaynakg, boyut * sizeof (wchar_t));
}
İşlev, hedef-geniş'in değeri ile döner.
Bu işlev ISO C90 standardının 1. düzeltmesinde tanımlanmıştır.
void *mempcpy
(void *restrict       hedef,
 const void *restrict kaynak,
 size_t               boyut)
işlev
mempcpy işlevi memcpy işlevi ile hemen hemen eşdeğerdir. İşlev, boyut baytı kaynak adresinden başlayan nesneden hedef adresine kopyalar. Fakat dönen değer hedef'in değeri değildir. hedef başlangıcından itibaren yazılan son baytı izleyen baytın adresi ile döner. Yani, dönen değer:
  ((void *) ((char *) hedef + boyut))
Bu işlev çok sayıda nesnenin ardışık bellek konumlarına kopyalanması durumunda kullanışlıdır.
void *
combine (void *o1, size_t s1, void *o2, size_t s2)
{
  void *result = malloc (s1 + s2);
  if (result != NULL)
    mempcpy (mempcpy (result, o1, s1), o2, s2);
  return result;
}
Bu işlev bir GNU oluşumudur.
wchar_t *wmempcpy
(wchar_t *restrict       hedef-geniş,
 const wchar_t *restrict kaynak-geniş,
 size_t                  boyut)
işlev
wmempcpy işlevi wmemcpy işlevi ile hemen hemen eşdeğerdir. İşlev, boyut geniş karakteri kaynak-geniş adresinden başlayan nesneden hedef-geniş adresine kopyalar. Fakat dönen değer hedef-geniş'in değeri değildir. hedef-geniş başlangıcından itibaren yazılan son geniş karakteri izleyen geniş karakterin adresi ile döner. Yani, dönen değer:
    hedef-geniş + boyut
Bu işlev çok sayıda nesnenin ardışık bellek konumlarına kopyalanması durumunda kullanışlıdır.
Aşağıda wmempcpy işlevinin olası bir gerçeklemesi vardır. Başka olası eniyilemeleri de vardır.
wchar_t *
wmempcpy (wchar_t *restrict hedefg, const wchar_t *restrict kaynakg,
         size_t boyut)
{
  return (wchar_t *) mempcpy (hedefg, kaynakg, boyut * sizeof (wchar_t));
}
Bu işlev bir GNU oluşumudur.
void *memmove
(void       *hedef,
 const void *kaynak,
 size_t      boyut)
işlev
memmove işlevi boyut baytı kaynak’tan hedef’e birbirlerinin üstüne binseler bile kopyalar. Üstüste binme durumunda, işlev, kaynak bloğundaki baytları hedef bloğuna dikkatle kopyalar.
İşlev, hedef'in değeri ile döner.
wchar_t *wmemmove
(wchar         *hedef-geniş,
 const wchar_t *kaynak-geniş,
 size_t         boyut)
işlev
memmove işlevi boyut geniş karakteri kaynak-geniş’ten hedef-geniş’e birbirlerinin üstüne binseler bile kopyalar. Üstüste bime durumunda, işlev, kaynak-geniş bloğundaki geniş karakterleri hedef-geniş bloğuna dikkatle kopyalar.
İşlev, hedef-geniş'in değeri ile döner.
Bu işlev bir GNU oluşumudur.
void *memccpy
(void *restrict       hedef,
 const void *restrict kaynak,
 int                  c,
 size_t               boyut)
işlev
Bu işlev boyut baytlık dizinin içindeki c karakterine kadar olan kısmı kaynak’tan hedef’e kopyalar. Dönen değer, hedef’e kopyalanan kısmın c karakterini izleyen baytının adresidir, eğer boyut bayt içinde c karakteri bulunamamışsa işlev boş gösterici ile döner.
void *memset
(void  *blok,
 int    c,
 size_t boyut)
işlev
Bu işlev, c değerini (unsigned char türüne dönüştürerek) blok adresinden başlayan nesnenin ilk boyut baytının her birine kopyalar ve blok’un değeri ile döner.
wchar_t *wmemset
(wchar_t *blok,
 wchar_t  wc,
 size_t   boyut)
işlev
Bu işlev, wc değerini blok adresinden başlayan nesnenin ilk boyut geniş karakterinin her birine kopyalar ve blok’un değeri ile döner.
char *strcpy
(char *restrict       hedef,
 const char *restrict kaynak)
işlev
strcpy işlevi kaynak dizgesini (sonlandırıcı boş karaktere kadar) hedef dizgesine kopyalar. Bu işlevde kaynak dizgesinin hedef dizgesinin üzerine binmesi durumundaki davranışı tanımsızdır. İşlev, hedef’in değeri ile döner.
wchar_t *wcscpy
(wchar_t *restrict       hedef-geniş,
 const wchar_t *restrict kaynak-geniş)
işlev
wcscpy işlevi kaynak-geniş dizgesini (sonlandırıcı boş geniş karaktere kadar) hedef-geniş dizgesine kopyalar. Bu işlevde kaynak-geniş dizgesinin hedef-geniş dizgesinin üzerine binmesi durumundaki davranışı tanımsızdır. İşlev, hedef-geniş’in değeri ile döner.
char *strncpy
(char *restrict       hedef,
 const char *restrict kaynak,
 size_t               boyut)
işlev
Bu işlev boyut sayıda karakteri hedef dizgesine kopyalamak dışında strcpy işlevi gibidir.
kaynak dizgesinin uzunluğu boyut bayttan uzunsa işlev, ilk boyut karakteri kopyalar. Bu durumda hedef dizgesi boş karakteri içermez.
kaynak dizgesinin uzunluğu boyut bayttan kısaysa kaynak dizgesi ile boş karakterden sonraki boyut bayta kadar olan baytlar boş karakterlerle doldurularak hedef dizgesine kopyalanır. Bu işlev az kullanışlıdır ama ISO C standardında belirtilmiştir.
Üstüste binme durumunda strncpy işlevinin davranışı tanımsızdır.
strncpy işlevinin kullanımı strcpy işlevinin aksine hedef için ayrılan alanın dışına taşan yazma ile ilgili yazılım hatalarından kaçınmak için bir yöntem sunar. Ancak, yazılımı yavaşlatır, çünkü büyük ihtimalle nispeten küçük bir dizgenin, oldukça büyük bir alana kopyalanması sözkonusu olacak ve dizgeden artan boş alanın boş karakterlerle doldurulması için boşuna zaman harcanacaktır.
wchar_t *wcsncpy
(wchar_t *restrict       hedef-geniş,
 const wchar_t *restrict kaynak-geniş,
 size_t                  boyut)
işlev
Bu işlev boyut sayıda geniş karakteri hedef-geniş dizgesine kopyalamak dışında wcscpy işlevi gibidir.
kaynak-geniş dizgesinin uzunluğu boyut geniş karakterden uzunsa işlev, ilk boyut geniş karakteri kopyalar. Bu durumda hedef-geniş dizgesi boş geniş karakteri içermez.
kaynak-geniş dizgesinin uzunluğu boyut geniş karakterden kısaysa kaynak-geniş dizgesi ile boş geniş karakterden sonraki boyut geniş karaktere kadar olan kısım boş geniş karakterlerle doldurularak hedef-geniş dizgesine kopyalanır. Bu işlev az kullanışlıdır ama ISO C standardında belirtilmiştir.
Üstüste binme durumunda wcsncpy işlevinin davranışı tanımsızdır.
wcsncpy işlevinin kullanımı wcscpy işlevinin aksine hedef-geniş için ayrılan alanın dışına taşan yazma ile ilgili yazılım hatalarından kaçınmak için bir yöntem sunar. Ancak, yazılımı yavaşlatır, çünkü büyük ihtimalle nispeten küçük bir dizgenin, oldukça büyük bir alana kopyalanması sözkonusu olacak ve dizgeden artan boş alanın boş geniş karakterlerle doldurulması için boşuna zaman harcanacaktır.
char *strdup
(const char *s)
işlev
Bu işlev boş karakter sonlandırmalı s dizgesini yeni bir bellek alanına kopyalar. Yeni dizge için yer ayırma işlemi malloc ile yapılır; bkz. Özgür Bellek Ayırma. malloc yeni dizge için yer ayıramazsa işlev boş gösterici ile döner, aksi takdirde yeni dizge için bir gösterici ile döner.
wchar_t *wcsdup
(const wchar_t *ws)
işlev
Bu işlev boş geniş karakter sonlandırmalı ws dizgesini yeni bir bellek alanına kopyalar. Yeni geniş karakterli dizge için yer ayırma işlemi malloc ile yapılır; bkz. Özgür Bellek Ayırma. malloc yeni geniş karakterli dizge için yer ayıramazsa işlev boş gösterici ile döner, aksi takdirde yeni geniş karakterli dizge için bir gösterici ile döner.
Bu işlev bir GNU oluşumudur.
char *strndup
(const char *s,
 size_t      boyut)
işlev
Bu işlev en fazla boyut karakteri kopyalamak dışında strdup işlevi gibidir.
s dizgesinin uzunluğu boyut bayttan uzun ise işlev ilk boyut baytı kopyalar ve sonuna bir boş karakter ekler, aksi takdirde tüm karakterler kopyalanır ve dizge sonlandırılır.
Bu işlev hedef dizgeyi daima bir boş karakter ile sonlandırması bakımından da strncpy işlevinden farklıdır.
strndup işlevi bir GNU oluşumudur.
char *stpcpy
(char *restrict       hedef,
 const char *restrict kaynak)
işlev
Bu işlev hedef dizgesinin sonunu gösteren bir gösterici ile dönmesi dışında strcpy işlevi gibidir.
Örneğin, bu yazılımda foo ve bar birleştirilerek foobar üretilmekte ve çıktılanmaktadır:
#include <string.h>
#include <stdio.h>

int
main (void)
{
  char tampon[10];
  char *hedef = tampon;
  hedef = stpcpy (hedef, "foo");
  hedef = stpcpy (hedef, "bar");
  puts (tampon);
  return 0;
}
Bu işlev ISO ya da POSIX standardının parçası değildir ve Unix sistemleri ile ilgili bir özel işlev de değildir. Tabii ki MS-DOS'dan geliyor.
Dizgelerin birbirinin üstüne binmesi durumundaki davranış tanımsızdır. İşlev string.h başlık dosyasında bildirilmiştir.
wchar_t *wcpcpy
(wchar_t *restrict       hedef-geniş,
 const wchar_t *restrict kaynak-geniş)
işlev
Bu işlev hedef-geniş dizgesinin sonunu gösteren bir gösterici ile dönmesi dışında wcscpy işlevi gibidir. İşlev kopyalanan dizgenin başlangıç adresi ile değil, dizgeyi sonlandıran boş geniş karakterin adresi ile döner.
Bu işlev bir ISO veya POSIX oluşumu değildir, ancak GNU C kütüphanesi geliştirilirken kullanışlı bulunmuştur.
Üstüste binme durumunda wcpcpy işlevinin davranışı tanımsızdır.
wcpcpy bir GNU oluşumudur ve wchar.h başlık dosyasında bildirilmiştir.
char *stpncpy
(char *restrict       hedef,
 const char *restrict kaynak,
 size_t               boyut)
işlev
Bu işlev, hedef’e ilk boyut karakteri kopyalaması dışında stpcpy gibidir.
kaynak dizgesinin uzunluğu boyut bayttan uzunsa işlev, ilk boyut karakteri kopyalar ve kopyalanan son karakterden sonraki baytın adresi ile döner. Bu durumda hedef dizgesi boş karakteri içermez.
kaynak dizgesinin uzunluğu boyut bayttan kısaysa kaynak dizgesinin boş karakterinden sonraki boyut bayta kadar olan baytlar boş karakterlerle doldurularak hedef dizgesine kopyalanır ve yazılan ilk boş karakterin adresi ile döner. Bu işlev az kullanışlıdır ama strncpy işlevinin davranışı kullanışlı bulunduğundan gerçeklenmiştir.
Bu işlev bir ISO veya POSIX oluşumu değildir, ancak GNU C kütüphanesi geliştirilirken kullanışlı bulunmuştur.
Dizgelerin birbirinin üstüne binmesi durumundaki davranış tanımsızdır. İşlev string.h başlık dosyasında bildirilmiştir.
wchar_t *wcpncpy
(wchar_t *restrict       hedef-geniş,
 const wchar_t *restrict kaynak-geniş,
 size_t                  boyut)
işlev
Bu işlev, hedef-geniş’e ilk boyut karakteri kopyalaması dışında wcpcpy gibidir.
kaynak-geniş dizgesinin uzunluğu boyut bayttan uzunsa işlev, ilk boyut geniş karakteri kopyalar ve kopyalanan son boş olmayan geniş karakterden sonraki geniş karaktere bir gösterici ile döner. Bu durumda hedef-geniş dizgesi boş geniş karakteri içermez.
kaynak-geniş dizgesinin uzunluğu boyut bayttan kısaysa kaynak-geniş dizgesinin boş geniş karakterinden sonraki boyut bayta kadar olan alanlar boş geniş karakterlerle doldurularak hedef-geniş dizgesine kopyalanır ve yazılan ilk boş geniş karakterin adresi ile döner. Bu işlev az kullanışlıdır ama wcsncpy işlevinin davranışı kullanışlı bulunduğundan gerçeklenmiştir.
Bu işlev bir ISO veya POSIX oluşumu değildir, ancak GNU C kütüphanesi geliştirilirken kullanışlı bulunmuştur.
Üstüste binme durumunda wcpncpy işlevinin davranışı tanımsızdır.
wcpncpy bir GNU oluşumudur ve wchar.h başlık dosyasında bildirilmiştir.
char *strdupa
(const char *s)
makro
Bu makro, malloc (Değişken Boyutlu Özdevinimli Saklama) yerine alloca kullanarak yeni bir dizge ayırmak dışında strdup gibidir. Yani, alloca kullanarak ayrılan bellek blokları ile aynı sınırlamalara sahip bir dizi döner.
Çeşitli sebeplerle strdupa sadece bir makro olarak gerçeklenmiştir; yani bir işlev gibi adresini alamazsınız. Bu sınırlama dışında bir işlev olarak kullanışlıdır. Aşağıdaki kodda malloc kullanıldığında işlemin ne kadar pahalıya malolduğu gösterilmiştir.
#include <paths.h>
#include <string.h>
#include <stdio.h>

const char path[] = _PATH_STDPATH;

int
main (void)
{
  char *wr_path = strdupa (path);
  char *cp = strtok (wr_path, ":");

  while (cp != NULL)
    {
      puts (cp);
      cp = strtok (NULL, ":");
    }
  return 0;
}
strtok'un doğrudan path kullanılarak çağrılmasının geçersiz olduğuna dikkat edin. Ayrıca, strdupa parametre aktarımında girişime sebep olabilen alloca'yı (Değişken Boyutlu Özdevinimli Saklama) kullandığından strtok'un argüman listesinde strdupa kullanımına izin verilmez.
Bu işlev sadece GCC ile kullanılabilir.
char *strndupa
(const char *s,
 size_t      boyut)
makro
Bu işlev, alloca kullanarak yeni bir dizge ayırmak dışında strndup gibidir. strdupa için geçerli olan yararlar ve sınırlamalar, strndupa için de geçerlidir.
Bu işlev de strdupa gibi sadece makro olarak gerçeklenmiştir. strdupa gibi bu makro da bir işlev çağrısının argüman listesinde kullanılamaz.
Bu işlev sadece GCC ile kullanılabilir.
char *strcat
(char *restrict       hedef,
 const char *restrict kaynak)
işlev
kaynak dizgesini hedef dizgesinin üzerine yazmak yerine hedef dizgesinin sonuna ekleyerek onunla birleştirmesi dışında strcpy işlevine benzer. kaynak dizgesinin ilk karakteri hedef dizgesini sonlandıran boş karakterin üzerine yazılır.
strcat işlevinin tanımı aşağıdakine eşdeğerdir:
char *
strcat (char *restrict hedef, const char *restrict kaynak)
{
  strcpy (hedef + strlen (hedef), kaynak);
  return hedef;
}
Dizgelerin üstüste binmesi durumu için bu işlevin davranışı tanımlanmamıştır.
wchar_t *wcscat
(wchar_t *restrict       hedef-geniş,
 const wchar_t *restrict kaynak-geniş)
işlev
kaynak-geniş dizgesini hedef-geniş dizgesinin üzerine yazmak yerine hedef-geniş dizgesinin sonuna ekleyerek onunla birleştirmesi dışında wcscpy işlevine benzer. kaynak-geniş dizgesinin ilk geniş karakterihedef-geniş dizgesini sonlandıran boş geniş karakterin üzerine yazılır.
wcscat işlevinin tanımı aşağıdakine eşdeğerdir:
wchar_t *
wcscat (wchar_t *hedefg, const wchar_t *kaynakg)
{
  wcscpy (hedefg + wcslen (hedefg), kaynakg);
  return hedefg;
}
Dizgelerin üstüste binmesi durumu için bu işlevin davranışı tanımlanmamıştır.
strcat ya da wcscat (ardından da strncat ya da wcsncar) işlevlerini kullanan yazılımcılar kolayca ihtiyatsız ve hatta deli olarak tanımlanabilir. Hemen hemen her durumda, ortak dizge uzunlukları bilinir (hem, tampon boyutunun yeterli olacağını kim bilebilir ki?). Veya en azından, çeşitli işlev çağrılarının sonuçları izlenerek bilinir. Ama yine de strcat/wcscat işlevleri yetersizdir. Kopyalama başladığında hedef dizgenin sonunu bulmak için gereksiz zaman harcanacaktır. Aşağıdaki örneğe bakınız:
/* Bu işlev birçok dizgeyi birleştirir.
   Son parametre NULL olmalıdır.  */
char *
concat (const char *dizge, …)
{
  va_list ap, ap2;
  size_t toplam = 1;
  const char *s;
  char *sonuc;

  va_start (ap, dizge);
  /* Aslında va_copy, ama geç dönem gcc sürümleri
     bu ismi tanır.
  __va_copy (ap2, ap);

  /* Bakalım, ne kadar yer lazımmış.  */
  for (s = dizge; s != NULL; s = va_arg (ap, const char *))
    toplam += strlen (s);

  va_end (ap);

  sonuc = (char *) malloc (toplam);
  if (sonuc != NULL)
    {
      sonuc[0] = '\0';

      /* Dizgeleri kopyalayalım.  */
      for (s = dizge; s != NULL; s = va_arg (ap2, const char *))
        strcat (sonuc, s);
    }

  va_end (ap2);

  return sonuc;
}
Basit gibi görünüyor, özellikle dizgelerin kopyalandığı ikinci döngü. Her biri 100 baytlık on dizgenin birleştirildiğini varsayalım. Aradığımız ikinci dizge için dizgenin sonunda zaten 100 bayt ayrıldığından sonraki dizgeyi ekleyebiliriz. Toplamda tüm dizgeler için ara sonuçlarla birlikte uzunluk 5500! olur. Bellek ayırma için yapılan arama ile kopyalamayı birleştirisek bu işlevi daha verimli kılabiliriz:
char *
concat (const char *dizge, …)
{
  va_list ap;
  size_t tutulan = 100;
  char *sonuc = (char *) malloc (tutulan);

  if (sonuc != NULL)
    {
      char *yeniwp;
      char *wp;

      va_start (ap, dizge);

      wp = sonuc;
      for (s = dizge; s != NULL; s = va_arg (ap, const char *))
        {
          size_t uzunluk = strlen (s);

          /* Gerekiyorsa, tutulan belleği arttıralım.  */
          if (wp + uzunluk + 1 > sonuc + tutulan)
            {
              tutulan = (tutulan + uzunluk) * 2;
              yeniwp = (char *) realloc (sonuc, tutulan);
              if (newp == NULL)
                {
                  free (sonuc);
                  return NULL;
                }
              wp = yeniwp + (wp - sonuc);
              sonuc = yeniwp;
            }

          wp = mempcpy (wp, s, uzunluk);
        }

      /* sonuclanan dizgeyi sonlandıralım.  */
      *wp++ = '\0';

      /* Belleği tam istenen boyuta ayarlayalım.  */
      yeniwp = realloc (sonuc, wp - sonuc);
      if (yeniwp != NULL)
        sonuc = yeniwp;

      va_end (ap);
    }

  return sonuc;
}
Girdi dizgeleri hakkına biraz daha fazla bilgi birikimi kullanarak bellek ayırma işlemi daha hassas yapılabilirdi. Burada farklı olarak strcat işlevini asla kullanmadık. Ara sonuçların izini sürerek dizge sonlarının bulunmasını güvenceye aldık ve mempcpy işlevini kullandık. Ayrıca, dizgeleri elde etmek bakımından daha doğal görünen stpcpy işlevini de kullanmadık. Ama zaten, dizge uzunluğunu bildiğimizden bu gerekli değildi ve bu sebeple daha hızlı bellek kopyalaması yapabildik. Örneğimiz geniş karakterler için de aynı şekilde çalışırdı.
Bir yazılımcı strcat kullanmaya karar vermeden önce iki kere düşünmeli ve hesaplanmış sonuçların getirilerinden yararlanmak için kod tekrar yazılamaz mı acaba diye bakmalıdır. Tekrarlayalım: strcat işlevinin kullanılması hemen hemen daima gereksizdir.
char *strncat
(char *restrict       hedef,
 const char *restrict kaynak,
 size_t               boyut)
işlev
Bu işlev, kaynak dizgesinin ilk boyut karakterini hedef dizgesinin sonuna eklemek dışında strcat gibidir. hedef dizgesinin sonuna daima bir boş karakter eklendiğinden hedef için ayrılan yer en azından boyut + 1 bayt olmalıdır.
strncat işlevi aşağıdaki gibi de gerçekleştirilebilirdi:
char *
strncat (char *hedef, const char *kaynak, size_t boyut)
{
  hedef[strlen (hedef) + boyut] = '\0';
  strncpy (hedef + strlen (hedef), kaynak, boyut);
  return hedef;
}
Dizgelerin üstüste binmesi durumu için bu işlevin davranışı tanımlanmamıştır.
wchar_t *wcsncat
(wchar_t *restrict       hedef-geniş,
 const wchar_t *restrict kaynak-geniş,
 size_t                  boyut)
işlev
Bu işlev, kaynak-geniş dizgesinin ilk boyut geniş karakterini hedef-geniş dizgesinin sonuna eklemek dışında wcscat gibidir. hedef-geniş dizgesinin sonuna daima bir boş geniş karakter eklendiğinden hedef-geniş için ayrılan yer en azından boyut + 1 bayt olmalıdır.
wcscat işlevi aşağıdaki gibi de gerçekleştirilebilirdi:
wchar_t *
wcsncat (wchar_t *restrict hedefg, const wchar_t *restrict kaynakg,
         size_t boyut)
{
  hedefg[wcslen (hedefg) + boyut] = L'\0';
  wcsncpy (hedefg + wcslen (hedefg), kaynakg, boyut);
  return hedefg;
}
Dizgelerin üstüste binmesi durumu için bu işlevin davranışı tanımlanmamıştır.
Aşağıdaki örnekte strncpy ve strncat kullanımı gösterilmiştir (Geniş karakterli olarak benzeri yazılabilir). strncat çağrısına dikkat edin, boyut parametresi tampon karakter dizisinin üste binmesine karşı korunarak hesaplanmıştır.
#include <string.h>
#include <stdio.h>

#define BOYUT 12

static char tampon[BOYUT];

main ()
{
  strncpy (tampon, "herkese", BOYUT);
  puts (tampon);
  strncat (tampon, " merhaba", BOYUT - strlen (tampon) - 1);
  puts (tampon);
}
Kod aşağıdaki gibi bir çıktı üretir:
herkese
herkese mer
void bcopy
(const void *kaynak,
 void       *hedef,
 size_t      boyut)
işlev
Bu işlev, BSD'den türetilen, memmove'un kısmen eskimiş bir alternafidir. Ancak memmove ile eşdeğer değildir, çünkü argümanları aynı sırada değildir ve dönen bir değer yoktur.
void bzero
(void  *blok,
 size_t boyut)
işlev
Bu işlev, BSD'den türetilen, memset'in kısmen eskimiş bir alternafidir. Ancak memset ile eşdeğer değildir, çünkü sakladığı tek değer sıfırdır.
Önceki Üst Ana Başlık Sonraki
Dizge Uzunluğu Başlangıç Dizi/Dizge Karşılaştırması
Bir Linux Kitaplığı Sayfası