C Programlama Dili'ne Giriş

  Dersler
* Önsöz

* Giriş
* Veri Tipleri, Değişkenler
* Operatörler
* Temel G/Ç Fonksiyonları
* Temel Kütüphane Fonksiyonları
* Karşılaştırma Deyimleri
* Döngüler
* Fonksiyonlar I
* Fonksiyonlar II
* Diziler
* Gösterici (Pointer) Kavramı
* Katarlar (Stringler)
* Dinamik Bellek Yönetimi
* Gösterici Uygulamaları
* Yapılar ve Birlikler
* Dosya Yönetimi
* Bit Düzeyinde Çalışmak
* Port Denetimi
* Grafik Kullanımı
* C Makroları

* Kısaca C++
* Derleme Seçenekleri
* Tarih-Saat Fonksiyonları
* Monte-Carlo Yöntemleri
* Fortran ve C

* Yararlanılan Kaynaklar

  C/C++ Derleyicileri
* Dev-C++
* Salford (silversoft FTN95)
* GCC
* Turbo C
* Eclipse IDE
* NetBeans IDE

  Dış Bağlantılar
* programlama.com
* C Programcıları Derneği

* C (wikipedia)
* C++ (wikipedia)
* cplusplus.com
* koders.com
* Hot scripts

 

Ders 12: Katarlar (Stringler)

###################- (%95)

En son güncelleme: Wed, 30 Nov 2011 13:22:02 +0200

Giriş

Katarlar anlaşılması en zor konulardan biridir. C programlama dilinde iki tırnak içine alınan her ifadeye katar denir. Örneğin:

     "Izmir"
     "sonuc = %d\n"
     "Devam etmek icin ENTER tusuna basin."
Türkçe yazılan C kitaplarda, ingilizce string kelimesi yerine aşağıdaki ifadelerden biri karşılaşılabilir:

katar = karakter topluluğu = karakter dizisi = sözce = sicim

Anlatımda, katar terimini kullanacağız.


12.1   Katar Bildirimi

Katarlar, char tipinde bildirilen karakter dizileridir ve harfler, rakamlar, veya bazı sembolleriden oluşur. C dilinde katar bildirimi için bir tip deyimi yoktur. Bu yüzden, bir katara bir dizi veya gösterici gözüyle bakılır. Genel olarak bir katarın bildirimi:

      char katar_adı[eleman_sayısı];
yada
      char *katar_adı;

şeklinde yapılır. Örneğin bir öğrencinin isim bilgisi ad adlı bir katarla tutulmak istenirse:

      char ad[10];
yada
      char *ad;

şeklinde programın başında bildirilmelidir.


12.2   Katarlara Başlangıç Değeri Atama

Diğer dizi bildirimlerinde olduğu gibi, karakter dizilerine başlangıç değeri verilebilir. Örneğin aşağıda verilen iki bildirim aynı anlamdadır:

     char s[5]={'I','z','m','i','r','\0'};
     char s[5]="Izmir";

Birinci satırdaki bildirimde '\0' (NULL) sonlandırıcı karakter dizisinin sonlandığını gösterir. Daha önce de bahsedildiği gibi sonlandırıcı karakter, karakter dizileri üzerinde işlemlerin hızlı ve etkin bir biçimde yapılabilmesine olanak sağlar. İkinci bildirimde buna gerek yoktur.

Eğer bir karakter dizisinin kaç eleman sayısı belirtilmezse, başlangıçta bildirilen karakter sayısı kaç tane ise dizinin eleman sayısı o kadar olduğu varsayılır.

      char s[] = "Ankara";    /* 6 elemanlı */

Eğer bildirim gösterici ile yapılmak isterirse:

      char *s = "Ankara";    /* 6 elemanlı */
yada
      char *s;
      s = "Ankara";
Ancak
      char s[6];
      s = "Ankara";

şeklindeki bir atama geçersizdir. Çünkü bu şekilde yapılan bildirimde s bir değişken değil dizidir.

Elemanları katar olan diziler tanımlamak mümkündür. Örneğin en uzunu 7 karakter olan 5 farklı isim bir çatı altında şöyle toplanabilir:

      char isim[5][8] = { "Semra", "Mustafa", "Ceyhun", "Asli", "Leyla" };
yada
      char isim[][8]  = { "Semra", "Mustafa", "Ceyhun", "Asli", "Leyla" };
yada
      char *isim[5]   = { "Semra", "Mustafa", "Ceyhun", "Asli", "Leyla" };

Görüldüğü gibi, bu tip tanımlamalarda birinci boyut (satır) dizinin eleman sayısını, ikinci boyut (sütun) her bir elemanın sahip olabileceği maksimum karakter sayısını gösterir.

 NOT
Katar ifadelerinde doğrudan çift tırnak " veya ters bölü \ karakterleri kullanılamaz. Bu durumda katar ifadeleri içerisinde

"   yerine   \"
\   yerine   \\

kullanılmalıdır. Örneğin:
   char *mes = "\"ilk.c\" dosyasinin yeri:";
   char *yol = "C:\\WINDOWS\\DESKTOP\\C";
   ...
   puts(mes);
   puts(yol);
ile ekrana aşağıdaki satırlar bastırlır:
   "ilk.c" dosyasinin yeri:
   C:\WINDOWS\DESKTOP\C


12.3   Katarlar Üzerinde İşlem Yapan Standart G/Ç Fonksiyonları

printf() ve scanf() fonksiyonları diğer tiplerde olduğu gibi formatlı okuma/yazma amaçlı kullanılır. Katar formatı %s dir. Örneğin:

     char str[20];
     ...
     scanf("%s",str);
     printf("%s\n",str);

satırları ile klavyeden okunan katarın ilk 20 karakteri ekrana yazdırlabilir. Burada printf() fonksiyonu:

      printf(str);

şeklinde de kullanılabir. Bu durumda, katar ekrana yazdırılır fakat imlec (cursor) bir alt satıra geçmez.

gets() fonksiyonu klavyeden karakter dizisi almakta kullanılan bir C fonksiyonudur. Bu fonksiyon, klavyeden girilen karakterleri diziye yerleştirdikten sonra dizinin sonuna otomatik olarak NULL ('\0') karakterini ekler.

      char str[20];
      ...
      gets(str);

 NOT
gets() fonksiyonunu kullanmak biraz tehlikeli olabilir.
Çünkü, gets() ile okuma yapılırken katarın büyüklüğünü dikkate alınmaz. Örneğin:
      char s[10];
      gets(s);
şeklindeki okuma işleminde s en fazla 10 karakter saklayabilirken, gets() ile 100 karakter girilirse, derleyici bütün karakterleri saklamaya çalışır. Bu durumda, program sağlıklı çalışmaz ve hata verir. Bu yüzden bazı derleyiciler, gets() kullanıldığında aşağıdaki gibi bir uyarı verir.
warning: the `gets' function is dangerous and should not be used.
Sonuç olarak, scanf() fonksiyonunu kullanmanız tavsiye edilir.

puts() fonksiyonu bir karakter dizisini ekrana yazdırmak için kullanılır. Bu fonksiyon diziyi ekrana yazdırdıktan sonra imleci (cursor) bir sonraki satıra geçirir.

      char *str = "Hangi cilgin bana zincir vuracakmis sasarim";
      ...
      puts(str);

puts(str) ile printf("%s\n",str) işlevsel olarak birbirine eşdeğerdir.

Buraya kadar anlatılanlar Program 12.1-3 de özetlenmiştir.

Program 12.1: Bir katarın farklı yöntemlerle ekrana yazdırılması
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
/* 12prg01.c
   Bir katarın farklı yöntemlerle ekrana yazılması */

#include <stdio.h>

int main()
{
     char dizi[7] = {'S', 'e', 'l', 'a', 'm', '!', '\0'};
     int i;

     /* Herbir karakteri ayrı ayrı alt alta yaz */
     printf("Dizi elemanlari:\n");
     for (i=0; i<7; i++)
        printf("dizi[%d] icerigi: %c\n", i, dizi[i]);
     printf("\n");

     /* 1. yöntem: her elemanı yanyana yaz */
     printf( "Butun dizi (1.yontem): ");
     for (i=0; i<7; i++)
        printf("%c", dizi[i]);

     /* 2. Yöntem: bütün diziyi yaz */
     printf("\nButun dizi (2.yontem): ");
     printf("%s\n", dizi);

     printf("\n");

 return 0;
}

ÇIKTI

Dizi elemanlari:
dizi[0] icerigi: S
dizi[1] icerigi: e
dizi[2] icerigi: l
dizi[3] icerigi: a
dizi[4] icerigi: m
dizi[5] icerigi: !
dizi[6] icerigi:

Butun dizi (1.yontem): Selam!
Butun dizi (2.yontem): Selam!

Aşağıdaki program kalvyeden girilen bir katar içindeki 'm' karakterlerinin sayısını blup ekrana yazar. İnceleyiniz.

Program 12.2: Bir katar içinde 'm' karakterinin sayısını öğrenme
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
/* 12prg02.c: Bir stringin içindeki 'm' karakterlerinin sayısı hesaplar */

#include <stdio.h>

int main()
{
   char str[20];
   int  i,sayac=0;

   printf("Bir string girin: ");
   gets(str);

   for(i=0; str[i] != '\0'; i++)
      if( str[i] == 'm') sayac++;

   printf("'m' karakteri sayisi = %d\n",sayac);

 return 0;
}

ÇIKTI

Bir katar girin: marmara
'm' karakteri sayisi = 2

13. satırdaki döngüde, str[i]!='\0', koşulu ile sonlandırıcı karaktere gelinip gelinmedği sorgulanmaktadır. 14. satırda katar içindeki 'm' karakterine rastlanırsa sayac değeri bir artmaktadır. Katar sonuna kadar bütün 'm' karakterlerinin toplamı hesaplanıp ekrana yazdırılmıştır.

Program 12.2'deki döngü şöyle de yazılabilirdi:

      ...
      for(i=0; str[i]; i++)
         if(str[i] == 'm') sayac++;
      ...

Buradaki işlemle str[i], NULL karakterinden farklı olduğu sürece döngü devam ettirilmiştir.

Aşağıdaki program elemanlı katar olan bir karakter dizisini ekrana yazar.

Program 12.3: Bir katarı yazdırma
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
/* 12prg03.c: Bir elemanları katar olan karakter dizisini yazdırma */

#include <stdio.h>

int main()
{
  char *gun[7] = { "Pazartesi", "Sali", "Carsamba", 
                    "Persembe", "Cuma", "Cumartesi", "Pazar" };
  int i;

  for(i=0; i<7; i++)
    printf("%d. %s\n",i+1,gun[i]);

 return 0;
}

ÇIKTI

1. Pazartesi
2. Sali
3. Carsamba
4. Persembe
5. Cuma
6. Cumartesi
7. Pazar


12.4   Bazı Katar Fonksiyonları

Bu fonksiyonlar standart C'de iki katarı karşılaştırmak, bir katarın içeriğini diğerine kopyalamak ve katarın uzunluğunu bulmak vb işlemler için tanımlı fonksiyonlardır. Bu ve benzeri fonksiyonlar kullanılırken string.h kütüphanesi programın başına ilave edilmelidir. Burada, bunlardan bir kaçı Tablo 12.1 de verilmiştir.

Tablo 12.1: string.h kütüphanesine ait, bazı katar fonksiyonları
Fonksiyon Açıklama
int strcmp(char *str1,char *str2); str1 ve str2 yi karşlaştırır.
Eşitse 0, str1 büyükse 0'dan büyük bir değer aksi halde 0'dan küçük bir değer göderir.
char *strcpy(char *str1, char *str2); str2 yi str1 e kopyalar
char *strcat(char *str1,char *str2); str2 yi str1 e ekler
char *strrev(str); str yi ters çevirir (NULL karakteri hariç)
int strlen(str); str nin kaç karakterden oluştuğunu hesaplar
char *strchr(char *str,char kr); kr karakterinin str içindeki (baştan itibaren) ilk karşılaştığı yeri verir
char *strstr(char *str1,char *str2); str2 katarının str1 içindeki (baştan itibaren) ilk karşılaştığı yeri verir
char *strlwr(char *str); str nin bütün karakterini küçük harfe çevirir
char *strupr(char *str); str nin bütün karakterini büyük harfe çevirir

Bu fonksiyonların kullanılması Program 12.4-8'de verilmiştir. Programları Dikkatle inceleyiniz.

Program 12.4: strcmp fonksiyonunun kullanımı
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
/* 12prg04.c: Basit bir şifre programı. 
   Kullanıcı en fazla 3 kez yanlış şifre girebilir. */

#include <stdio.h>
#include <string.h>

int main()
{
   char sifre[8];
   int  sonuc, hak=3;

   while( hak-- > 0 )
   {
      printf("Sifre : ");
      gets(sifre);                    /* şifreyi al */

      sonuc = strcmp(sifre,"elma%xj4");

      if( sonuc==0 ){                 /* şifre kontrol */
         puts("sifre dogru");
         break;
      }
      else
         puts("sifre yanlis");
   }

  return 0;
}

ÇIKTI

Sifre : admin
sifre yanlis
Sifre : root
sifre yanlis
Sifre : elma%xj4
sifre dogru



Program 12.5: strcpy fonksiyonunun kullanımı
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
/* 12prg05.c: Bir katarı diğerine kopyalama */

#include <stdio.h>
#include <string.h>

int main()
{
   char str1[] = "Deneme";
   char str2[15], str3[15];
   int  i;

   /* strcpy kullanarak  kopyalama */
   strcpy(str2, str1);

   /* strcpy kullanmadan kopyalama */
   for(i=0; str1[i]; i++)
      str3[i] = str1[i];
   str3[i] = '\0';      /* sonlandırıcı ekle */

   /* sonuçlar ekrana */
   printf("str1 : %s\n",str1);
   printf("str2 : %s\n",str2);
   printf("str3 : %s\n",str3);

 return 0;
}

ÇIKTI

str1 : Deneme
str2 : Deneme
str3 : Deneme



Program 12.6: strcat fonksiyonunun kullanımı
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
/* 12prg06.c: Bir katarı diğerine ekler */

#include <stdio.h>
#include <string.h>

int main()
{
   char mesaj[20] = "Selam ";  /* 1. katar */
   char  isim[10];             /* 2. katar */

   printf("Adiniz ? : ");
   scanf("%s",isim);

   /* ekle */
   strcat(mesaj, isim);

   printf("%s\n",mesaj);

 return 0;
}

ÇIKTI

Adiniz ? : Mert
Selam Mert



Program 12.7: strlen fonksiyonunun kullanımı
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
/* 12prg07.c: Bir karakter dizisinin uzunluğunu bulur */

#include <stdio.h>
#include <string.h>

int main()
{
   char s[20];
   int  k = 0;

   printf("Bir seyler yazin : ");
   scanf("%s",s);

   /* sonlandırıcı karaktere kadar */
   while( s[k] != '\0' )
         k++;
 
   puts("Dizinin uzunlugu");
   printf("strlen kullanarak  = %d\n",strlen(s));
   printf("strlen kullanmadan = %d\n",k);

 return 0;
}

ÇIKTI

Bir seyler yazin : deneme stringi
Dizinin uzunlugu
strlen kullanarak  = 14
strlen kullanmadan = 14



Program 12.8: Isim sırlama
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
/* 12prg08.c
   Kabarcık Sıralama (Bubble Sort) Algoritması ile
   isimleri alfabetik sırayla listeler */

#include <stdio.h>
#include <string.h>

#define n  5

int main()
{
  char isim[n][8] = { "Semra", "Mustafa", "Ceyhun", "Asli", "Leyla" };
  char  gecici[8];
  int i,j,k;

  puts("Once:\n------");
  for(i=0; i<n; i++)
     printf("%s\n",isim[i]); 
  
  /* sırala */
  for(k=0; k<n-1; k++)
  for(j=0; j<n-1; j++)
    if( strcmp(isim[j],isim[j+1]) > 0 )  /* isim[j]>isim[j+1] ? */
    {
      strcpy(gecici   ,isim[j]);
      strcpy(isim[j]  ,isim[j+1]);
      strcpy(isim[j+1],gecici);
    }

  puts("\nSonra:\n------");  
  for(i=0; i<n; i++)
     printf("%s\n",isim[i]);

 return 0;
}

ÇIKTI

Once:
------
Semra
Mustafa
Ceyhun
Asli
Leyla

Sonra:
------
Asli
Ceyhun
Leyla
Mustafa
Semra


12.5   Katarların Fonksiyonlarda Kullanılması

Katarların fonksiyonlara parametre olarak geçirilmesi durumuna sıklıkla rastlanır. Gerçekte fonksiyona parametre olarak aktarılan karakter dizisini gösteren bir adrestir. Bu yüzden karakter dizileri fonksiyonlara çoğunlukla gösterici tipinde geçirilir.

Aşağıdaki iki örnekte yazılan struzn ve strcev fonksiyonları sırasıyla strlen ve strrev fonksiyonların dengi niteliğindedir. Burada kullanılan benzer mantıkla, string.h kütüphanesindki birçok fonksiyon yazılabilir. İnceleyiniz.

Program 12.9: strlen dengi bir fonksiyon: struzn
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
/* 12prg09.c: Bir katarın uzunluğunu bulan strlen dengi bir fonksiyon */

#include <stdio.h>
#include <string.h>

int struzn(char *);

int main()
{
  char *s;

  printf("Bir katar girin: ");  
  gets(s);

  printf("Uzunlugu (struzn) : %d\n",struzn(s));
  printf("Uzunlugu (strlen) : %d\n",strlen(s));

 return 0;
}

/* bir karakter dizisinin uzunluğunu hesaplar */
int struzn(char *str)
{
  int n = 0;

  while(str[n]) 
     n++;

  return n;
}

ÇIKTI

Bir katar girin: Programlama
Uzunlugu (struzn) : 11
Uzunlugu (strlen) : 11



Program 12.10: strrev dengi bir fonksiyon: strcev
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
/* 12prg10.c: Bir katarın tersini veren bir fonksiyon */

#include <stdio.h>
#include <string.h>

char *strcev(char *);

int main()
{
  char s[50];

    printf("Bir katar girin: ");  
    scanf("%s",s);

    printf("Katar, s : %s\n",s);
    printf("Tersi, strcev(s) : %s\n",strcev(s));

 return 0;
}

/* str katarını ters-yüz eder */
char *strcev(char *str)
{
  int  i,n;
  char gecici;

  n = strlen(str);

  for(i=0; i<n/2; i++)
  {
     gecici     = str[i];
     str[i]     = str[n-i-1];
     str[n-i-1] = gecici;
  }

  return str; /* geri dönüş değeri bir gösterici */
}

ÇIKTI

Bir katar girin: Programlama
Katar, s : Programlama
Tersi, strcev(s) : amalmargorP



Powered by PHP