LINUX.ORG.RU
ФорумTalks

[Совсем оффтопик] Русская локаль и Windows


0

0

Тут такое дело, перевожу кроссплатформенную консольную софтину на gettext. Проблема в том, что софтине надо выводить сообщения в консоль и в лог и отправлять текст на некоторый сервер. Проблема в том, что в случае венды в консоль нужно cp866, в лог надо cp1251. А на сервер всегда надо юникод.

.mo'шники все будут для UTF-8. Кто-нибудь подскажет как будет выглядеть следующий код, чтобы Print1 выводило текст в кодировке консоли, а Print2 - в кодировке системы (в линуксе-то оно, ясен пень, совпадает с первым, но в винде-то всё иначе).

void Print1( string message )
{
cout << message << endl;
}

void Print2( string message )
{
secondout << message << endl;
}

Заранее спасибо. В /D/ не стал постить, так как уж очень оффтопично.

★★★★★

man 3 iconv

и кодировать сообщения в зависимости от назначения из utf-8 в то что надо.

vyv ★★★
()

В консоль можно и юникодными функциями выводить... На MSDN...

anonymfus ★★★★
()

>в лог надо cp1251

Там даже notepad, помнится, понимал UTF-8/16. Зачем 1251?

Deleted
()
Ответ на: комментарий от Obey-Kun

в винде есть winAPI функции для определения текущих кодировок.

vyv ★★★
()
Ответ на: комментарий от Relan

Вау, звучит неплохо. Но тогда это под линуксом как надо не заработает :).

Я вижу 2 решения:
1) Забить на неюникодных пользователей Linux
2) Так выводить в кодировке консоли

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

Пойду по второму пути. Есть GetConsoleCP. Кажется, мне этого хватит. И хрен с ним с логом, пусть будет в юникоде.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Relan

Нет, не катит

http://forum.ixbt.com/topic.cgi?id=26:39262

Юзеру придётся шрифт в консоли менять.

Заюзаю GetConsoleOutputCP(). Осталось разобраться с тем, как заставить софтину понять, винда у нас или линукс. Кто-нибудь поможет кодом? То есть, надо так: если у нас винда, то конвертируем somestring из UTF-8 в GetConsoleOutputCP(), иначе конвертируем somestring из UTF-8 в локаль системы. Пожалуйста :).

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от cobold

Не могу сказать точно, ими было пользоваться настолько "удобно" что их считай не было (:

kapsh
()
Ответ на: комментарий от cobold

Спасибо :). Только там не совсем __linux__, там просто "иначе". Так что

#ifdef _WIN32
...
#else
...
#endif

Причём использовать это мы будем в начале файла (чтоб подгрузить, если надо, виндовскую либу) и в месте, где мы занимаемся перекодировкой. Осталось разобраться с тем, как получить просто локаль и как перекодировать текст :).

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

Можно унаследовать класс от std::ostream (пусть он будет называться eostream) и перегрузить оператор eostream& << (eostream&, const char*). А уже внутри реализации перекодировать. Соответственно, в программе придется использовать типы потоков вывода, это минус.

Relan ★★★★★
()
Ответ на: комментарий от Obey-Kun

> Блин, а что означают эти упавшие минусы? То бишь, почему _WIN32, а не WIN32?

Мой вам совет: не ищите логики в потрохах Windows. Ее там нет.

Relan ★★★★★
()
Ответ на: комментарий от Relan

Да тут всё гораздо проще. Нужно научить вот этот код перекодировать текст как надо:

void CONSOLE_Print( string message )
{
	cout << message << endl;

	// logging

	if( !gLogFile.empty( ) )
	{
		ofstream Log;
		Log.open( gLogFile.c_str( ), ios :: app );

		if( !Log.fail( ) )
		{
			time_t Now = time( NULL );
			string Time = asctime( localtime( &Now ) );

			// erase the newline
			
			Time.erase( Time.size( ) - 1 );
			Log << "[" << Time << "] " << message << endl;
			Log.close( );
		}
	}
}

Осталось осилить iconv и locale.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Relan

Я так понимаю, это от выбора девелопера зависит. И в разных софтинах для опеределения того, какая ось дефайнят то WIN32, то _WIN32, а то и вовсе _WIN32_. То есть, стандарта нету, всё зависит от девелопера, правильно понимаю?..

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

если склероз мне ни с кем не изменяет макросы начинающиеся с _[A-Z] и __ зарезервированы под системные нужды. Посему прикладной программист не должен их использовать.

cobold ★★★★★
()
Ответ на: комментарий от cobold

Короче, в этом проекте уже используется дефайн WIN32. Задаётся он, я так понимаю, компилятором:

obey@damntux trunk % cat ghost/ghost.vcproj | grep WIN32
                                PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
                                PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
                                PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;GHOST_MYSQL"
                                PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;GHOST_MYSQL"

Короче, с определением ОСи всё ясно. А что с определением системной локали и, собственно, перекодировкой?

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

> А что с определением системной локали и, собственно, перекодировкой?

При таком раскладе зачем вам вообще знать про локаль? Под #ifdef WIN32 перекодируйте с помощью AnsiToOem()/OemToAnsi() да и всё.

Relan ★★★★★
()
Ответ на: комментарий от Obey-Kun

Внезапно задумался над вопросом "а что будет задефайнено при сборке под 64bit Windows"? Возможно придётся доработать условие ☺

cobold ★★★★★
()
Ответ на: комментарий от Relan

Ясно. Но под линуксом всё равно надо перекодировать...

Obey-Kun ★★★★★
() автор топика

О спорах по поводу дефайнов... Я не пойму, Вы все что, в windows.h заглянуть не можете? Начинается он с _WINDOWS_

anonymfus ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.