iconv Örnekleri
Önceki Soysal Karakter Kümesi Dönüşümü Sonraki
iconv Örnekleri
Aşağıdaki örnekte ortak bir soruna bir çözüm sunulmaktadır. wchar_t dizgeleri için sistem tarafından bilinen kodlamalar verilmiştir. Metin bir dosyadan okunmakta ve geniş karakter tamponunda saklanmaktadır. Dönüşüm mbsrtowcs kullanılarak da yapılabilirdi fakat evvelce basettiğimiz sorunlar oluşurdu.
int
file2wcs (int fd, const char *charset, wchar_t *outbuf, size_t avail)
{
  char inbuf[BUFSIZ];
  size_t insize = 0;
  char *wrptr = (char *) outbuf;
  int result = 0;
  iconv_t cd;

  cd = iconv_open ("WCHAR_T", charset);
  if (cd == (iconv_t) -1)
    {
      /* Yanlış giden birşeyler olabilir.  */
      if (errno == EINVAL)
        error (0, 0, "'%s' için wchar_t cinsinden bir karşılık yok",
                charset);
      else
        perror ("iconv_open");

      /* Çıktı dizgesini sonlandıralım.  */
      *outbuf = L'\0';

      return -1;
    }

  while (avail > 0)
    {
      size_t nread;
      size_t nconv;
      char *inptr = inbuf;

      /* Girdinin kalanını okuyalım.  */
      nread = read (fd, inbuf + insize, sizeof (inbuf) - insize);
      if (nread == 0)
        {
          /* Buraya gelimişsek okuma tamamlanmıştır. Ama hala
             inbuf içinde kullanılmamış
             karakterler kalmış olabilir. Onları geri koyalım.  */
          if (lseek (fd, -insize, SEEK_CUR) == -1)
            result = -1;

          /* Gerekliyse, ilk duruma girecek bayt dizilimini yazalım. */
          iconv (cd, NULL, NULL, &wrptr, &avail);

          break;
        }
      insize += nread;

      /* Dönüşümü yapalım.  */
      nconv = iconv (cd, &inptr, &insize, &wrptr, &avail);
      if (nconv == (size_t) -1)
        {
          /* Herşey yolunda gitmez. Tamponun sonunda bitmemiş
             bir bayt dizilimi olabilir. Kimi zaman da gerçekten
             önemli bir sorun olabilir.
          if (errno == EINVAL)
            /* Bu zararsız. Kullanılmayan baytları tamponun başına
               taşıyalım ki, sonraki adımda onlar kullanılabilsin.  */
            memmove (inbuf, inptr, insize);
          else
            {
              /* Bu gerçekten bir sorun. Ya çıktı tamponu yetersiz
                 ya da girdi geçersizdir. Her durumda, dosya
                 göstericisini işlenen son baytın konumuna
                 ayarlayacağız.  */
              lseek (fd, -insize, SEEK_CUR);
              result = -1;
              break;
            }
        }
    }

  /* Çıktı dizgesini sonlandıralım.  */
  if (avail >= sizeof (wchar_t))
    *((wchar_t *) wrptr) = L'\0';

  if (iconv_close (cd) != 0)
    perror ("iconv_close");

  return (wchar_t *) wrptr - outbuf;
}

Bu örnek, iconv işlevlerinin en önemli kullanım şekillerini göstemektedir. Büyük boyutta bir metnin iconv çağrılarıyla nasıl dönüştürülebileceği gösterilmiştir. Kullanıcı durumsal kodlamalar hakkında birşey bilmek zorunda değildir.
iconv işlevinin errno değişkenine EINVAL değerini atayarak döndüğü durum ilginçtir. Bu gerçekte dönüşümdeki bir hata değildir. Girdi karakter kümesinin tek parça olarak işlenemeyen metinler ve bir bayttan uzun bayt dizilimleri içermesine bağlı olarak oluşur. Bu durumda çokbaytlı dizilimin bölünmesi olasılığı vardır. Çağrıcı basitçe bu sorunlu baytları atlayıp girdiden kalan baytları okuyup iconv'ye aktararak dönüşümü devam ettirebilir. ISO C standardında böyle bir olay sonrasındaki duruma bağlı olarak dönüşüm işlevlerinin tanımlayıcıda tutulan dahili durum bilgisinin ne olacağı belirtilmemiştir.
Ayrıca, örnekte iconv işlevinde geniş karakterli dizgelerin kullanımına bağlı sorunlar da gösterilmiştir. iconv işlevinin açıklamasında belirtildiği gibi, işlev daima bir char dizisi alır, dolayısıyla bu dizinin boyutu bayt cinsindendir. Örnekte ise çıktı tamponu bir geniş karakter tamponudur; bu nedenle iconv çağrısında char* türünde olan wrptr yerel değişkenini kullandık.
Bu oldukça masum görünür ama hizalama konusunda sıkı sınırlamaları olan platformlarda sorunlara yol açabilir. Bu nedenle bu tür iconv çağrılarında ilgili karakter kümesindeki karakterlere erişmek için uygun bir gösterici kullanılmalıdır. İşlevin girdi parametresi bir wchar_t göstericisi olduğundan bu sağlanmıştır (aksi takdirde parametre hesaplanırken hizalama bozulacaktı). Fakat diğer bir durumda, özellikle kullanılan karakter kümesi türünün bilinmediği soysal işlevler yazılırken metinler bayt dizilimleri olarak ele alındığından bu çok zor olabilir.
Önceki Üst Ana Başlık Sonraki
Soysal Dönüşüm Arayüzü Başlangıç Diğer iconv Gerçeklemeleri
Bir Linux Kitaplığı Sayfası