tr-demoscene

the scene => coding => console => Konuyu başlatan: akvamlar57 - 14.02.2011 10:20:45

Başlık: c++ Türkçe karakter sorunu
Gönderen: akvamlar57 - 14.02.2011 10:20:45
Bir eğitim setinden çalışıyorum. Adam devamlı Türkçe karakter kullanmaktan kaçınıyor. Bozuk çıktığından dolayı konsol uygulamalarında sorun varmış. Bunu nasıl çözebilirim.
Başlık: c++ Türkçe karakter sorunu
Gönderen: skate - 14.02.2011 10:48:20
@akvamlar57: çözmen biraz güç. aslında yöntemleri var ancak karakterleri remap etmen gerekir. yani ya sen source code'da türkçe karakter yerine başka birşey yazacaksın ya da her zaman bir filitre fonksiyonun olacak, burada karakterler remap edilecek. şunun gibi birşey;
 
Kod: [Seç]
char* remapChars(char* text) {
    // burada karakterleri uygun karşılıklarıyla değiştir
    // ı gördüğün yere XX kodlu karakteri koy gibi
}
 
void main() {
    cin >> remapChars("türkçe karakter testi: ğüşıöçğÜşıÖÇ");
}

remapChars'ı yazmak sana kalıyor elbette ki. Ancak bence bunlara hiç kafa yorma. Zaten özel bir tool falan kodlamıyorsan, ileride yapacağın uygulamaların çoğunda konsol ile pek alakan olmayacaktır. Öğrenme sürecinde de Türkçe karakter kullanmayıver. :)
Başlık: c++ Türkçe karakter sorunu
Gönderen: nightlord - 14.02.2011 18:59:16
akvamlar: hangi compiler'i kullaniyorsun?
 
turkce karakterle ilgili iki konu var:
- yazdigin programin icinde turkce karakter olan stringleri isleyebilmesi: bu gayet kolay cozulur mesela VC++'da #define UNICODE demen ve butun stringler icin wstring, wchar vs kullanman yeterli
 
- yazdigin koddaki fonksiyon isimleri degisken isimleri gibi yerlerde Turkce karakter kullanmak: Bunu cozmek zor (hatta mumkun olup olmadigini bilmiyorum bile). Hic kasmana gerek yok.
Başlık: c++ Türkçe karakter sorunu
Gönderen: skate - 14.02.2011 19:31:33
ben "konsol çıktısında sorun var" şeklinde algılayarak cevaplamıştım. akvamlar57, biraz daha detay verir misin?
Başlık: c++ Türkçe karakter sorunu
Gönderen: akvamlar57 - 14.02.2011 23:10:38
konsol çıktısında sorun vardı doğru tahmin etmişsin. Dediğiniz gibi öğrenme sürecinde fazla önemsemedim
Başlık: c++ Türkçe karakter sorunu
Gönderen: skate - 15.02.2011 02:05:09
şimdi biraz bakındım, sanırım kernel32.dll içinde yer alan "SetConsoleOutputCP(uint codePage)" bu işi çözüyormuş. .NET'deki karşılığı da Console::OutputEncoding. şimdilik kafa yorma ama dersen ki "bugün çok boş vaktim var...", sana ipucu. :)
Başlık: c++ Türkçe karakter sorunu
Gönderen: scg - 15.02.2011 02:20:36
Nightlordun önerdiği çözüm windows ta VC++ ile gelen compiler ile işe yarayabilir. ışe yarayabilir diyorum Win32 API ile işe yarayacağından eminim.
Adamlar tüm API yi

Kod: [Seç]
#ifdef UNICODE
#define CreateWindow CreateWindowW
#else
#define CreateWindow CreateWindowA
#endif
şeklinde yazdıkları için.

Elimin altında windows ve VC++ yok , saf C++ ile işe yarar mı deneyemedim şimdi.

Linux ve GCC ( g++ )  de durum şöyle:

C++ ın lokalizasyon kütüphanesini kullanmak lazım. Sanırım libstdc++ sırtını yüklü
sistem locale lerine dayıyor. setlocale(...) ile türkçeyi set edememiştim. Sonra
sistemdeki (Ubuntu 10.10) locale leri terminalden :

Kod: [Seç]
locale -a ile query ettim.

Türkçe yoktu. Sonra

Kod: [Seç]
sudo locale-gen tr_TR.UTF-8türkçeyi ekledim.

Bunu yaptıktan sonra setlocale(..) çalıştı. Geriye de ASCII dışındaki
karakterler için wchar_t veri tipini ve her türlü stream (console i/o , file i/o)
in bu veri tipiyle çalışan versiyonlarını kullanmak kaldı.

Sanırım biraz kodla daha anlaşılır olur:

Kod: [Seç]
#include      // locale
#include   // file stream


// locale string in windows may be: "Turkish_Turkey.1252" test this.
const char* locStr = ::setlocale(LC_ALL , "tr_TR.utf8");  
std::locale loc(locStr);
std::wcout.imbue(loc);

// console output
const wchar_t* test = L"şşğğüÜçÇıI";
std::wcout<<"Unicode: "<
// file i/o
    std::wfstream ifs("şğşçııı.txt");

    if(ifs.is_open()){

        std::wcout<<"Yepp - file is open"<
        ifs.close();
    }

// console input
    wchar_t buff[100];
    std::wcout<<"Enter..."<    std::wcin >> buff;

    std::wcout<<"Entered text: "<
Başlık: c++ Türkçe karakter sorunu
Gönderen: anesthetic - 16.02.2011 14:58:30
@scg: kullandığın editörde (eclipse, kwrite, gedit vs.) encodingi utf-8 yapsan yeterli. hatta sanırım üçünde de artık default böyle. shelller de default utf-8 geldiği için hiçbir şey yapmana gerek kalmıyor.

Kod: [Seç]
#include <iostream>

int main()
{
    std::cout << &quot;fıstıkçı şahap&quot; << std::endl ;
    return 0 ;
}


not: "locale -a" bende de türkçe getirmiyor. (ubuntu 10.10)
Başlık: c++ Türkçe karakter sorunu
Gönderen: scg - 17.02.2011 00:43:25
@Anes: Encoding konusunda haklısın. Default utf-8. Ama..anladığım kadarıyla char *Linux* da zaten unicode. Farkında olmadan unicode kullanıyormuşum zaten :)

şuna bak:

Kod: [Seç]
   char hede[]  = &quot;fıstıkçı&quot;;
    char hede2[] = &quot;fistikci&quot;;

    int size1 = sizeof(hede);
    int size2 = sizeof(hede2);

    std::cout<<&quot;size1: &quot;<<size1<<std::endl;
    std::cout<<&quot;size2: &quot;<<size2<<std::endl;

    int len1 = ::strlen(hede);
    int len2 = ::strlen(hede2);

    std::cout<<&quot;len1: &quot;<<len1<<std::endl;
    std::cout<<&quot;len2: &quot;<<len2<<std::endl;

    std::cout<<&quot;hede:  &quot;<<hede<<std::endl;
    std::cout<<&quot;hede2: &quot;<<hede2<<std::endl;
Çıktısı da :

Kod: [Seç]
size1: 13
size2: 9
len1: 12
len2: 8
hede:  fıstıkçı
hede2: fistikci
Bunun (ı , ç gibi karakterler 2 byte) portable olduğunu sanmıyorum. Windows da açıkça wchar_t - std::wstring  falan kullanmak gerekebilir. Windows & VC++ elimin altında değil deneyemiyorum , denemeye üşeniyorum.
Başlık: c++ Türkçe karakter sorunu
Gönderen: anesthetic - 17.02.2011 01:38:24
@scg: char unicode değil, char bir bytelık tamsayı. dolayısıyla char* içine birer bytelara ayrılmış her şeyi koyabiliriz. buna utf-8 diziler de dahil.

şimdi diyelim ki editör (eclipse, notepad, visual studio vs.) utf-8 dosyayla çalıştığını biliyor olsun. sen 'ğ' ekleyince dosyaya utf-8'de 'ğ''ya karşılık gelen bytelar ekleniyor. burada 2 byte ama başka karakterler için 1, 3, 4, 5... de olabilir. editör bu iki byte'ı ekranda 'ğ' olarak gösteriyor ama dosyada orada iki byte var.

gcc için char datasının encodingi diye bişey yok. o sadece sayıları depoluyor. kaç byte girilmişse strlen o kadar dönüyor. strlen kullanma zaten, unicode için özel tasarlanmış bir string sınıfı kullan.

konsola yazarken de shell, utf-8 yazacağını biliyorsa byteları inceleyip 'ğ' karakteri basıyor.

grafik arayüz olayı içinse kullandığın framework (gtk, qt) verdiğin byte dizilerinin utf-8 olduğunu varsayıp ona göre işlem yapıyor.

microsoft'un derleyicileri de farklı çalışmıyor. daha önce utf-8 hazırladığım kodu derlediğimde sorun yaşamadım. arayüz için winapi yerine qt kullandım ama. winapi'de başına gelecek sıkıntılar şunlar olabilir:

- microsoft'un toolları (notepad dahil) utf-8 dosyaların başına byte order mark (bom) koyuyor. python filan sıkıntı çekiyor onu parse ederken. utf-8'de byte order diye bir şey olmadığı için çok saçma bir olay aslında.
- winapi için unicode utf-16 (wchar) demek. utf-16 portable değil, (byte order) space efficient değil, içinde sıfırlar var :/ utf-8 ise kat kat daha portable (orada gördüğün ı için kullanılan iki byte her yerde aynı)
- winapi dünyasında her şey (data, kod, dosya) ya unicode ya değil. her şeyi önceden bunu düşünüp tasarlaman gerekiyor. diğer yandan her ascii string aynı zamanda geçerli bir utf-8 string olduğu için ve utf-8 içinde '\0' baytı bulunmadığı için, utf-8 seven toollar kullandığında istemeden unicode compliant kodlar üretmiş oluyorsun.
- utf-8 gibi süpersonik bir teknolojiyi göz ardı edip ıskalarsan, herkes mersin'e giderken tersine gitmiş olursun :)

taa 2003'lerden sesleniyorum sana scg :)
http://www.joelonsoftware.com/articles/Unicode.html
Başlık: c++ Türkçe karakter sorunu
Gönderen: skate - 17.02.2011 02:13:05
makaledeki her coder unicode ve karakter setleri hakkında bilgi sahibi olmalıdır lafı doğru ama eksik. sadece unicode bilmek de her zaman fayda etmiyor. benim gibi unicode desteklemeyen ancient dillerden arabic language support da yapıcan ki tam olsun. :) karakter birleşme kurallarını ne zaman hatırlarsam öğürüyorum.