Forum: D Programlama Dili RSS
Konsol Türkçe Karakter Hatası
Sayfa:  önceki  1  2  3  sonraki 
emre413 (Moderatör) #16
Kullanıcı başlığı: Celal Emre ÇİÇEK
Üye Tem 2009 tarihinden beri · 62 mesaj · Konum: Kırıkkale
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj ID 9949
agora:
emre413:
Enteresan bir şekilde D için kodları denediğimde kod olarak 65001 kabul gördü, 1254 değil. D için şöyle bir kod yazdım:

import std.stdio;
import core.sys.windows.windows;
 
extern(Windows) {
    bool SetConsoleCP(uint wCodePageID);
    bool SetConsoleOutputCP(uint wCodePageID);
}
 
void main() {
    SetConsoleCP(65001);
    SetConsoleOutputCP(65001);
 
    stdout.writeln("Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş");
}

bu kod çalıştı. 65001 yerine 1254 yazınca karakterler bozuk çıktı. Aynı API fonksiyonu ancak farklı değer istiyor, garip! :)

Bende hala calismadi 65001 ya da 1254 :(

öncelikle komut satırı özelliklerinden yazı tipini Lucida Console yapmak gerekiyor. Ali hocamın da dediği gibi çıkış UTF-8 olsa bile konsolun bunu algılaması gerekli. Lucida Console UTF-8 karakter encodingini destekliyor. Windows'un varsayılan Consolas yazı tipi desteklemiyor.
emre413 (Moderatör) #17
Kullanıcı başlığı: Celal Emre ÇİÇEK
Üye Tem 2009 tarihinden beri · 62 mesaj · Konum: Kırıkkale
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj ID 9948
acehreli:
emre413:
c++ için döküman encodingini UTF-8 yapınca bu sefer de D'de olduğu gibi 65001 çalıştı

Öyle yapınca kaynak kod içindeki dizgi hazır değeri içindeki ü karakteri de dizgide iki bayt yer tutmaya başladı. (strlen ile bakabilirsin.) Dolayısıyla, ü karakteri iki bayt ile temsil ediliyorsa konsolun da o iki bayta karşılık ü'yü gösterecek biçimde ayarlanması şart.

Ali

evet hocam dediğiniz gibi.

    const char* cumle = "ŞşÜü";
 
    int len = strlen(cumle);
 
    cout << "len = " << len << endl;

çıktı olarak len = 8 veriyor.
agora #18
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #16
emre413:
agora:
emre413:
Enteresan bir şekilde D için kodları denediğimde kod olarak 65001 kabul gördü, 1254 değil. D için şöyle bir kod yazdım:

import std.stdio;
import core.sys.windows.windows;
 
extern(Windows) {
    bool SetConsoleCP(uint wCodePageID);
    bool SetConsoleOutputCP(uint wCodePageID);
}
 
void main() {
    SetConsoleCP(65001);
    SetConsoleOutputCP(65001);
 
    stdout.writeln("Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş");
}

bu kod çalıştı. 65001 yerine 1254 yazınca karakterler bozuk çıktı. Aynı API fonksiyonu ancak farklı değer istiyor, garip! :)

Bende hala calismadi 65001 ya da 1254 :(

öncelikle komut satırı özelliklerinden yazı tipini Lucida Console yapmak gerekiyor. Ali hocamın da dediği gibi çıkış UTF-8 olsa bile konsolun bunu algılaması gerekli. Lucida Console UTF-8 karakter encodingini destekliyor. Windows'un varsayılan Consolas yazı tipi desteklemiyor.

O zaman konsol fontunu degistirmek gerekiyo galiba. Burada iste onceki mesajlarda yazdigim WideChar ve MultiByteTo fonksiyonlarinin kullanimi gerekiyo ancak o D'de var mi bilmiyorum. Onu kullanarak da UTF-8 vs. ayarlamalar yapilabiliyordu.
emre413 (Moderatör) #19
Kullanıcı başlığı: Celal Emre ÇİÇEK
Üye Tem 2009 tarihinden beri · 62 mesaj · Konum: Kırıkkale
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
agora galiba sen kod ile konsol fontunu değiştirmekten bahsediyorsun? öyleyse onun nasıl yapıldığını bilmiyorum ancak ben manuel olarak fontu değiştirdiğimde çalışıyor. Hemen araştırıyorum kod ile nasıl yapıldığını :)
acehreli (Moderatör) #20
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #18
agora:
O zaman konsol fontunu degistirmek gerekiyo galiba.

Evet, bazı fontlar yalnızca ASCII ve bir kaç karakter tablosunu destekleyecek kadar kısıtlıdırlar. Unicode'u destekleyen font kullanmak şart.

Burada iste onceki mesajlarda yazdigim WideChar ve MultiByteTo fonksiyonlarinin kullanimi gerekiyo

Ondan emin değilim. Programın kodlamasıyla konsolun kodlaması uyduğu sürece onlara gerek yok. Onlar WideChar vs. kullanan API'lerden gelen dizgileri dönüştürmek için yararlı olabilirler.

Ali

İlgisiz not: Yanıt yazarken iki seçenek var:

1) Mesajın üstündeki "Alıntı yap": Bunu seçerseniz yanıtladığınız metin olduğu gibi kopyalanıyor. Özellikle yanıtlanan yerini belirtmek için diğer taraflarını kırpmak gerekiyor. Külfetli...

2) Sayfanın altındaki "Yanıtla": Bunu seçerseniz boş pencere geliyor. Ekonomik. :)
agora #21
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #19
emre413:
agora galiba sen kod ile konsol fontunu değiştirmekten bahsediyorsun? öyleyse onun nasıl yapıldığını bilmiyorum ancak ben manuel olarak fontu değiştirdiğimde çalışıyor. Hemen araştırıyorum kod ile nasıl yapıldığını :)

Evet evet. Cunku bu islemlerin manuel olarak yapilmasi pek saglikli degil yani saglik demeyeyim de yorucu olabilir. Otomasyona ugramasi daha guzel olmaz mi?

Duzenleme:

Ali hocam afedersiniz tekrar olmaz haklisiniz tesekkur ederim :)
Bu mesaj agora tarafından değiştirildi; zaman: 2013-08-22, 15:14.
emre413 (Moderatör) #22
Kullanıcı başlığı: Celal Emre ÇİÇEK
Üye Tem 2009 tarihinden beri · 62 mesaj · Konum: Kırıkkale
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
agora:
Evet evet. Cunku bu islemlerin manuel olarak yapilmasi pek saglikli degil yani saglik demeyeyim de yorucu olabilir. Otomasyona ugramasi daha guzel olmaz mi?

Duzenleme:

Ali hocam afedersiniz tekrar olmaz haklisiniz tesekkur ederim :)

Biraz araştırma yaptım. Bir kod buldum ama düzgün çalışmıyor. Derleniyor (yalnızca Visual C++ ile yani D'ye adapte edebilir miyiz bilemiyorum) ancak konsol yazı tipini değiştiremiyor.

#include "stdafx.h"
#include <windows.h>
#include <conio.h>
#include <iostream>
 
using namespace std;
 
int main( int, char *[] )
{
    PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx = new CONSOLE_FONT_INFOEX;
    
    lpConsoleCurrentFontEx->cbSize = sizeof(CONSOLE_FONT_INFOEX);
 
    GetCurrentConsoleFontEx(GetStdHandle (STD_OUTPUT_HANDLE), NULL, lpConsoleCurrentFontEx); //retrive all console font informations
 
    swprintf_s(lpConsoleCurrentFontEx->FaceName, L"Lucida Console");
 
    SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), NULL, lpConsoleCurrentFontEx);
 
    SetConsoleCP(1254);
    SetConsoleOutputCP(1254);
 
        cout << "Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş" << endl;
 
    delete lpConsoleCurrentFontEx;
 
    system("PAUSE");
    return EXIT_SUCCESS;
}

Bu kodun sorunu ne olabilir? Derleniyor ancak herhangi bir işlev görmüyor. Font değişmiyor.

Sorunu bulabilir miyiz, bulsak da kodu D'ye adapte edebilir miyiz bilemiyorum.

Ekleme:

Bu dediğim ayar bir kereliğine yapılıyor. Yani her programı çalıştırdığımızda yapmak zorunda değiliz. Biraz amatörce bir yaklaşım olacak ama :) projelerde kullanıcıya ayarın nasıl yapılacağını gösteren bir açıklama yapsak, Ali hocam burada ayarın nasıl yapılacağını anlatmış.
Bu mesaj emre413 tarafından değiştirildi; zaman: 2013-08-22, 16:15.
agora #23
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Çok ilginç ama bende girişten alınan bilgilerin Türkçe karakter sorunu yok. Kaynak kodda var bu sorun.. Yani kullanıcı'dan girişten değer alınırsa Türkçe karakterde sorun yok. Ancak kaynak kodda belirlenmiş bir karakteri ekrana yazdırınca sorun var.

İlk Değer Çıktısı =>

Test surusu
 
ğüşçöoı // girilen değer
k1471065822dF42C48511C2F31FA01449C28202B84849223372036854775808b // kendi şifrelememle olan değer
 
ğüşçöoı // girilen değeri daha sonra tekrar yazdırdım
Press any key to continue . . .

Yani bu koda bakacak olursak ilk girdiğim değeri tekrar ekrana vurunca örneğin

string a;
 
Sifreleme(a);
 
writeln(a);

Çıktılar doğru düzgün. Şimdi benim de aklımda bi soru işareti oldu. Madem kaynak koddan çıkanlarda Türkçe karakter sorunu var.. O zaman Sifreleme() işlevini main.d içinde kullandığımda türkçe karakterleri bozuk mu çıkarıyor kafam karıştı da.

Bir işlevi değer aldığı anda ekrana yazdırabiliyor muyuz? Örneğin

writeln("Test surusu\n");
    string a = chomp(readln());


    Sifreleme(a); /* s output: q1471065822r03C7C0ACE395D80182DB07AE2C30F0349223372036854775808l */


Ben onu writeln(Sifreleme(a)); yaparsam hata verecekmis gibi hissediyorum.

Duzenleme:

Az onceki ilk değer çıktısında girilen değerin Türkçe çıktı verdiğini görüyoruz. Büyük ihtimal o zaman şifrelenen değerin içerikleri de Türkçe ama bir de şuna bakın

İkinci Değer Çıktısı =>

Test surusu
 
ğşıöçü
s1471065822o06FC4859709791CA520C0B8A88BE48859223372036854775808a
─ş┼ş─▒├Â├ğ├╝ // hata var
Press any key to continue . . .

Burada hata var diye belirttiğim kısım kullanıcıdan değer alınarak değil, manuel olarak kaynak kodda writeln içinde yazdırılıyor.

Şimdi merak ettiğim şey.. Kullanıcıdan değer alınca sorun yok, ama kendimiz manuel yazdirinca neden sorun var karakterde?
Bu mesaj agora tarafından değiştirildi; zaman: 2013-08-22, 16:30.
emre413 (Moderatör) #24
Kullanıcı başlığı: Celal Emre ÇİÇEK
Üye Tem 2009 tarihinden beri · 62 mesaj · Konum: Kırıkkale
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Ben de bir şeyler denedim şimdi. Ancak durum gerçekten ilginç. Konsol yazı tipim Lucida Console. Kod:

import std.stdio;
import core.sys.windows.windows;
import std.string;
 
extern(Windows) {
    bool SetConsoleCP(uint wCodePageID);
    bool SetConsoleOutputCP(uint wCodePageID);
}
 
void main() {
    SetConsoleCP(65001);
    SetConsoleOutputCP(65001);
 
    write("Bir String Girin: ");
    string a = chomp(readln());
 
    writeln("Girilen String: ", a);
 
    stdout.writeln("Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş");
}

Çıktı (String olarak Türkçe karakter içeren bir string girildi):

Bir String Girin: çööçöçüğüğ
Girilen String:
Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş
 
Process returned 0 (0x0)   execution time : 7.768 s
Press any key to continue.

Çıktı (String olarak Türkçe karakter içermeyen bir string girildi):

Bir String Girin: asdasd
Girilen String: asdasd
Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş
 
Process returned 0 (0x0)   execution time : 1.433 s
Press any key to continue.

Yani bende de kullanıcı string girdiğinde problem var, kendim string bastığımda problem yok :)
agora #25
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Çok ilginç bi konu oldu hoşuma gitti bu :)

Bu arada ilk değerin çalışma zamanı 7.768 s bu IDE ile mi alakali acaba?
emre413 (Moderatör) #26
Kullanıcı başlığı: Celal Emre ÇİÇEK
Üye Tem 2009 tarihinden beri · 62 mesaj · Konum: Kırıkkale
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
agora:
Çok ilginç bi konu oldu hoşuma gitti bu :)

Bu arada ilk değerin çalışma zamanı 7.768 s bu IDE ile mi alakali acaba?

yok ya o programın toplam çalışma süresi. ben değer girerken beklediğim için öyle oldu. o kadar da kötü donanımlı bir bilgisayar kullanmıyorum :)
Bu mesaj emre413 tarafından değiştirildi; zaman: 2013-08-22, 17:32.
acehreli (Moderatör) #27
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #22
emre413:
Derleniyor (yalnızca Visual C++ ile yani D'ye adapte edebilir miyiz bilemiyorum) ancak konsol yazı tipini değiştiremiyor.

Belgesine baktım:

  http://msdn.microsoft.com/en-us/library/windows/desktop/ms…

Hata olduğunda dönüş değeri 0 oluyormuş. Ne hata olduğu GetLastError ile öğreniliyormuş.

swprintf_s doğru kullanılıyor mu? Belgesinde en az üç parametre almalı gibi görünüyor:

  http://msdn.microsoft.com/en-us/library/ce3zzk1k.aspx

Gözüme bir şey daha takıldı: SetCurrentConsoleFontEx'in ikinci parametresi bool olduğu halde NULL gönderiliyor. bool ise false olmalı.

Ali
emre413 (Moderatör) #28
Kullanıcı başlığı: Celal Emre ÇİÇEK
Üye Tem 2009 tarihinden beri · 62 mesaj · Konum: Kırıkkale
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
swprintf_s doğru kullanılıyor mu? Belgesinde en az üç parametre almalı gibi görünüyor:

O belgede alt tarafta iki tane tanım var galiba fonksiyon bunlara binaen öyle kullanılmış. Çünkü derleme hatası vermedi.

template <size_t size>
int sprintf_s(
   char (&buffer)[size],
   const char *format [,
   argument] ... 
); // C++ only
 
template <size_t size>
int swprintf_s(
   wchar_t (&buffer)[size],
   const wchar_t *format [,
   argument]...
); // C++ only 

Ancak kodu 3 parametreli olarak da çağırdım Ali hocam yeni hali şöyle ancak baştan belirteyim yine çalışmıyor :(

#include "stdafx.h"
#include <windows.h>
#include <conio.h>
#include <iostream>
 
using namespace std;
 
int main( int, char *[] )
{
    PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx = new CONSOLE_FONT_INFOEX;
 
    lpConsoleCurrentFontEx->cbSize = sizeof(CONSOLE_FONT_INFOEX);
 
    GetCurrentConsoleFontEx(GetStdHandle (STD_OUTPUT_HANDLE), NULL, lpConsoleCurrentFontEx); //retrive all console font informations
 
    int swpResult = swprintf_s(lpConsoleCurrentFontEx->FaceName, 15, L"Lucida Console");
 
    cout << "Son Hata, swprintf_s'den Sonra: " << GetLastError() << endl;
 
    int sccfResult = SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), false, lpConsoleCurrentFontEx);
 
    cout << "Son Hata, SetCurrentConsoleFontEx'ten Sonra: " << GetLastError() << endl;
    cout << "swpResult: " << swpResult << endl;
    cout << "sccfResult: " << sccfResult << endl;
 
    SetConsoleCP(1254);
    SetConsoleOutputCP(1254);
 
    cout << "Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş" << endl;
 
    delete lpConsoleCurrentFontEx;
 
    system("PAUSE");
    return EXIT_SUCCESS;
}

Çalışma Sonucu:

Son Hata, swprintf_s'den Sonra: 0
Son Hata, SetCurrentConsoleFontEx'ten Sonra: 0
swpResult: 14
sccfResult: 1
Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş
Devam etmek için bir tuşa basın . . .

Buraya kopyalayınca çıktıdaki Türkçe karakterler düzgün göründü ama konsolda bozuk görünüyor.

SetCurrentConsoleFontEx 1 döndürmüş yani başarılı, swprintf_s de yazdığı karakter sayısını döndürüyormuş. Normal olarak 14 döndürdü.

Çıktı penceresinin özelliklerinden fontu elle Lucida Console yapınca doğru görünüyor karakterler bu arada.
emre413 (Moderatör) #29
Kullanıcı başlığı: Celal Emre ÇİÇEK
Üye Tem 2009 tarihinden beri · 62 mesaj · Konum: Kırıkkale
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sanırım bir şeyler buldum :)

#include "stdafx.h"
#include <iostream>
#include <io.h>
#include <fcntl.h>
 
int main( int, char *[] )
{
    _setmode(_fileno(stdout), _O_U8TEXT);
 
    wprintf(L"Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş\n");
 
    system("PAUSE");
 
    return 0;
}

Bu kod çalıştı tüm karakterler doğru basıldı ve Lucida Console yazı tipine dönüştürmeye gerek kalmadı. Yazı tipi hala Tarama Yazı Tiplerindeyken problemsiz tüm karakterleri doğru olarak bastı :)

Ek olarak:

D ile deneyeyim dedim, şöyle bir kod yazdım ama hata verdi:

import std.stdio;
import core.sys.windows.windows;
import std.string;
 
extern(Windows) {
    int _setmode(int _FileHandle, int _Mode);
    int _fileno(FILE *_File);
}
 
void main() {
    const int _O_U8TEXT = 0x40000;
 
    _setmode(_fileno(stdout), _O_U8TEXT);
    stdout.writeln("Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş");
}

Hata: hello.d|15|Error: function hello._fileno (shared(_iobuf)* _File) is not callable using argument types (File)|

cast(FILE*)stdout denedim yine olmadı.
Bu mesaj emre413 tarafından değiştirildi; zaman: 2013-08-22, 21:08.
acehreli (Moderatör) #30
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
emre413:
Hata: hello.d|15|Error: function hello._fileno (shared(_iobuf)* _File) is not callable using argument types (File)|

cast(FILE*)stdout denedim yine olmadı.

_fileno'nun parametresi FILE* imiş. D'nin stdout'u ise bir std.stdio.File diye bir struct. Tabii cast de olmaz çünkü bir yapı nesnesini FILE göstergesi olarak kullanmaya çalışıyoruz.

File'ın getFP üye işlevi sarmaladığı FILE göstergesini döndürür:

  http://dlang.org/phobos/std_stdio.html#.File.getFP

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  önceki  1  2  3  sonraki 
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 09:18:34 (UTC -08:00)