August 22, 2013

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 :)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

Ç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?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

Alıntı (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 gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

Alıntı (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.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

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 gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

Evet hocam onu buldum ama buraya henüz yazmamıştım. Sonra şöyle bir şey denedim:

import std.stdio;
import core.sys.windows.windows;
import std.string;

extern(C) {
   int wprintf(const wchar *format,...);
}

void main() {
   const int _O_U8TEXT = 0x40000;

   setmode(fileno(stdout.getFP()), _O_U8TEXT);
   wprintf("Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş");
}

wprintf tanımında wchar_t yerine wchar kullandım ondan mı oldu bilmiyorum ancak karakterler doğru basılmadı. Bu arada o getFP olayını düzeltince _setmode ve _fileno fonksiyonlarını tanımadı. Galiba zaten std.stdio'da bu fonksiyonlar tanımlı imiş. Ondan dolayı setmode ve fileno kullanınca tanıdı. Program çalıştı ancak doğru işlev görmedi.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

Alıntı (emre413):

>

Enteresan bir şekilde D için kodları denediğimde kod olarak 65001 kabul gördü, 1254 değil.

D programı UTF-8 işlediğine göre 65001 olması gerekir çünkü Unicode'un 1254 numaralı kod tablosundaki karakter kodlarıyla ilgisi yok.

Alıntı:

>

65001 yerine 1254 yazınca karakterler bozuk çıktı.

D çalışma ortamı karakterleri girişten teker teker alıyor ve onları UTF-8 kodları olarak kabul ediyor. Dolayısıyla konsolun ü'yü temsil etmek için UTF-8'deki karşılığı olarak girişe 2 bayt yerleştirmesi şart. Bunu değiştirmek olanaksız.

Aynı şey çıkış için de gerekli. D programı ü'yü çıkışa 2 bayt olarak yazdırıyor. Doğru işlemesi için konsolun da UTF-8'e ayarlı olması şart. Yoksa o iki baytın 1254'te karşılık geldikleri iki karakter olarak yazdırır.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

Alıntı (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

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

Alıntı (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.

Alıntı:

>

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. :)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

Alıntı (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/ms686200%28v=vs.85%29.aspx

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

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]