PDA

Tam Sürümünü Görmek İçin : C programlama string içerisindeTürkçe karakter arama,karşılaştırma,değiştirme...


kcetinkaya
28/01/2008, 22:19
void *turkce_karakter_donustur(char *ptr)
{
char karakterler[]={'ç','ğ','ı','ö','ş','ü','Ç','Ğ','İ','Ö','Ş','Ü'} ;
int a,b;
for (a=0;ptr[a]!='\0';a++)
for (b=0;b<12;b++)
if (ptr[a]==karakterler[b])
switch (ptr[a]) {
case 'ç': ptr[a]='c'; break;
case 'ğ': ptr[a]='g'; break;
case 'ı': ptr[a]='i'; break;
case 'ö': ptr[a]='o'; break;
case 'ş': ptr[a]='s'; break;
case 'ü': ptr[a]='u'; break;
case 'Ç': ptr[a]='C'; break;
case 'Ğ': ptr[a]='G'; break;
case 'İ': ptr[a]='I'; break;
case 'Ö': ptr[a]='O'; break;
case 'Ş': ptr[a]='S'; break;
case 'Ü': ptr[a]='U'; break;
}
}


C için böyle bir fonksiyon yazdım. Klavyeden alacağımız string ifade içerisindeki Türkçe karakterleri çevirecek bir fonksiyon. main içerisinde gets() fonku ile string ifadeyi alıyorum fonksiyona da gönderiyorum ifademi ancak ne yaptımsa doğru çalıştıramadım.
if (ptr[a]==karakterler[b]) burdaki if içerisine hiç bir zaman girmiyor doğal olarak da değiştirme işlemini yapmıyor.

Sorun Türkçe karakterlerin karşılaştırılmasında. Fonksiyonun yazımında bir sorun yok. Aynı kalıbı kullanarak istediğim normal bir karakteri değiştirebiliyorum, dizi üzerinde değişiklik yapabiliyorum.

C çalıştığım Kaan Aslan ın kitabında türkçe karakter sayısını veren benzer bir örnek :


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100
int gettrknum(const char *str);
int main()
{
char s[SIZE];
printf("Yaziyi giriniz : ");
gets(s);
printf("Turkce karakter sayisi : %d",gettrknum(s));
return 0;
}
int gettrknum(const char *str)
{
int counter=0;
int i;
char trk[]="çğıöşüÇĞİÖŞÜ";
for (i=0;str[i]!='\0';i++)
if (strchr(trk,str[i])) counter++;
return counter;
}


şeklinde yazılmış. Kitaptan aynen alıntı yaptım. Ancak bu programı çalıştırmayı denediğimde de ekrana her zaman 0 değerini basıyor. Yani burdada aynı sorun strchr() fonksiyonu ile türkçe karakter araması yaptığımda sorun ortaya çıkıyor. Normal bir karakter denedğim de çok güzel çalışıyor.

IDE olarak CodeBlocks ve Turbo C de denedim sonuç aynı.

Sorunun çözümüne yardımcı olursanız sevinirim...


acehreli
28/01/2008, 23:29
if denetiminden once ptr[a] ve karakterler[b]'nin tamsayi degerlerini yazdirirsan (%d ile) bir yardimi olabilir:

printf("%d %d\n", ptr[a], karakterler[b]);

Ali

-aga-
29/01/2008, 08:20
İf'i kaldırsan ne olur?

2. for, if ve karakterler[] bence gereksiz.

Tabi bu çözüm değil. Program İ harfi girilince ÿ olarak tanıyor herhalde. Bu yüzden ascii değerlerini kullanmalısın.

kcetinkaya
29/01/2008, 17:17
Kim önce diyecek diye bekliyordum :)

Şu an yaptığı iş için içteki for tabii ki gereksiz tek for içinde bir else if merdiveni veya aynı şekilde switch deyimi karşılayabilir yaptığı işi. Neden böyle yazdın derseniz ilk olarak sadece Türkçe karakter sayısını sayması için yazmıştım fonksiyonu yani switch deyimi yerine sayac++; diye tek satır kod vardı sonra biraz daha genişleteyim dedim direk switch deyimini kopyala yapıştır yaptım bu haliyle de direk buraya ekledim. Sonradan farkettim açıkçası :)

Herneyse algoritma yanlışlığını bir kenara bırakıp sorunun çözümüne gelelim. Sorunu basit bir örnekle size şöyle bir daha açıklayayım :

#include <stdio.h>

void main() {
char chistr[10],str[10];
ch='ç';
gets(str);
printf("%c %d \n",ch,ch);
printf("%c %d \n",str[0],str[0]);
}

Yukarıdaki koda input olarak "çetin" girdiğinizi düşünün bu durumda str[0]='ç' olacaktır
değil mi ? Kodun ekrana verdiği çıktı ise :
-25
ç -121
şeklinde oluyor. Yani kodun içerisinde yazdığım kullandığım 'ç' karakteri ile string ifade
girerken kullandığım 'ç' karakteri aynı yorumlanmıyor. Sorun ascii tablosunda 127 den
büyük olan her karakter için geçerli. Tahminim, atama işlemi veya karşılaştırma gibi
işlemler yapılırken işaretli işaretsiz otomatik olarak yapılan tür dönüşümlerinden
meydana gelen bit kaybı gibi bir şey esas sorun. Ama daha fazla bir fikrim yok ve nasıl
çözeceğim konusunda.

Hadi kendi yazdığım kodu geçtim Kaan Aslan ın yazdığı kodda çalışmıyor :) O kodda da aynı sorun var benimki ile strchr() işlevi de kabul etmiyor türkçe karakterleri normal bir karakter yazarsam zehir ibi çalışıyor ikisi de :P

İki gündür bunla uğraşıyorum internette araştırıyorum çok zaman harcıyorum yav :S hala tatmin edici bir açıklama bulamadım. Eskiden buralarda sordunmu hemen cevaplarlardı :P Eski kullanıcı adımı unutmuşum :)

acehreli
29/01/2008, 19:07
Programi yazdigin ortamin yaptigi varsayimlarla programi calistirdigin ortamin yaptigi varsayimlar farkli. Ornegin Emacs'te; klavyeden girerken, dosyaya kaydederken, baska programlardan kopyala/yapistirirken kullanilan karakter tablolari ayri ayri belirlenebilir.

Bir kodun ne anlama geldigi ve ekranda nasil gorundugu o kadar da belirli bir olay degil. Senin ortaminda calisabilmek icin, karakterler'i %d'nin gosterdigi degerlerle doldurmayi dene. Boylece o calisma ortamiyla uyumlu olursun. Her ortamda calisabilmek icin herhalde Unicode'u destekleyen bir kutuphane gerekir.

Ali

kcetinkaya
30/01/2008, 00:08
tamamdır hallettim ... ilgilenen arkadaşlara teşekkür ederim.

kodlama içerisinde yazdığım 'ç' ile string ifade içerisinde girdiğim 'ç' karakterinin farklı yorumlanması kullandığım derleyicinin (CodeBlocks) türkçe karakter desteklememesinden kaynaklanıyormuş. (Ali hocamım dediği gibi ortam farklılığı) Yazdığım kodları makine diline çevirirken 'ç' gördüğü yerde farklı davranıyor.
Yoksa Kaan Aslan da yanlış yazacak değil ya :)

Karşılaştırma işini de istediğim karakterlerin ascii kodlarını kullanarak yaptım bu durumda. Örneğin 'ç' yi aramak için ç karakterinin ascii kodu olan 135 ile " if (c==135) .. " şeklinde yaptım.

Tabi bir diğer sorun girilen 'ç' karakterinin ascii kodunu ekrana gerçek olan 135 değil de -121 olarak yazdırmasıydı. Bunun da sebebi ekrana çıktı alınırken char veri türünün integera çevrilmesi ve çevrilirken negatifliğin korunması amacıyla yüksek anlamlı bitlerin hepsinin 1 yapılması. Aynı şekilde if (c==135) karşılaştırması da yanlış oluyordu bu durumda, karakterin son değeri -121 olması sebebiyle. Bu sorunu da istediğim karakterleri kontrol etmek için tanımladığım diziyi char olarak değil de işaretsiz türden tanımlayarak hallettim.

Şimdi zehir gibi çalışıyor :)