Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно определить кодовую страницу 
:(
    Опции темы
vns955
Дата 1.6.2009, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 21.11.2006

Репутация: нет
Всего: нет



Всем зрям!

Мне нужно определить текущую кодовую страницу и передать ее в setlocale(). Т.е чтоб такой код работал:

Код

   setlocale(LC_ALL, ".866");
   std::wcout.imbue(std::locale(".866"));

   wstring sStr = _T("Привет Мир");
   wcout << sStr << endl;

Это для руского языка, но если у меня например текущей будет немецкая кодовая то она должна как-то определиться из системы и быть передана в ф-ции setlocale() и imbue() и вывод на немецком должен корректно отображаться в консольном приложении. Вопрос: как правильно определить кодовую страницу которую надо подставить в упомянутые ф-ции? Использование ф-ций GetConsoleCP(), GetACP() и GetOEMCP() не увелчалось успехом. :(
Использую VS2003, стоит в настройках: Unicode character Set,   (/Zc:wchar_t),  (/Zc:forScope) в Language.

Спасибо


PM MAIL   Вверх
586
Дата 1.6.2009, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Код
#include <stdio.h>
#include <locale.h>

int main(int argc, char* argv[])
{
   setlocale(LC_ALL, "");   // кодировка по умолчанию
   wprintf(L"Привет мир!\n");
    return 0;
}

PM   Вверх
GremlinProg
Дата 1.6.2009, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



GetSystemDefaultLCID дает локаль принятую в системе
GetUserDefaultLCID дает локаль принятую для текущего пользователя

GetLocaleInfoEx - это общий метод, позволяющий извлекать разные данные локали по ее идентификатору,
например: язык, страна, страница OEM, ACP и т.п.

GetSystemDefaultLocaleName
GetUserDefaultLocaleName - тут все аналогично с первыми двумя, только вместо локали возвращается ее имя (частный случай функции GetLocaleInfo)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
vns955
Дата 1.6.2009, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 21.11.2006

Репутация: нет
Всего: нет



Пробовал подставлять то что возвращают ф-ции GetSystemDefaultLCID() и GetUserDefaultLCID() - не получилось :(
PM MAIL   Вверх
GremlinProg
Дата 1.6.2009, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(vns955 @  2.6.2009,  01:10 Найти цитируемый пост)
Пробовал подставлять то что возвращают ф-ции GetSystemDefaultLCID() и GetUserDefaultLCID() - не получилось :(

это поставлять в setlocale и не нужно,
но можно подставлять строковые: GetSystemDefaultLocaleName, GetUserDefaultLocaleName,
а GetSystemDefaultLCID() и GetUserDefaultLCID() можно подставлять в GetLocaleInfoEx, чтобы извлечь информацию

если нужна кодовая страница, как в примере, типа setlocale(LC_ALL, ".866"), то для этого есть несколько флагов к GetLocaleInfoEx:
LOCALE_IDEFAULTANSICODEPAGE - это флаг для получения ANSI-кодировки для заданной локали
LOCALE_IDEFAULTCODEPAGE  - это флаг для получения OEM-кодировки для заданной локали
только из GetLocaleInfoEx при этом вернется просто номер страницы, без точки, так что тут перед подстановкой в setlocale надо дополнительно формировать строку из этого номера (не помню только в бинарном виде или в строковом)

либо использовать просто флаг LOCALE_SENGLANGUAGE - язык локали по английски, т.е. соответственно:
для GetSystemDefaultLCID - язык, принятый в системе
для GetUserDefaultLCID - язык, принятый для пользователя

Добавлено через 14 минут и 39 секунд
Цитата(GremlinProg @  2.6.2009,  01:36 Найти цитируемый пост)
не помню только в бинарном виде или в строковом

по идее, можно и так и так, есть флаг LOCALE_RETURN_NUMBER, правда я не нашел его в онлайн документации


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
GremlinProg
Дата 1.6.2009, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



а, все понял, смотрел в CE, вот верная ссылка: http://msdn.microsoft.com/en-us/library/dd464799(VS.85).aspx



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
vns955
Дата 2.6.2009, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 21.11.2006

Репутация: нет
Всего: нет



GetLocaleInfoEx() поддерживает минимум Windows Server 2008, а я программирую под Server 2003. Можно ли обойтись без этой ф-ции?
PM MAIL   Вверх
GremlinProg
Дата 2.6.2009, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(vns955 @  2.6.2009,  15:02 Найти цитируемый пост)
GetLocaleInfoEx() поддерживает минимум Windows Server 2008

вообще-то она даже в XP присутствует,
я ее использовал без проблем,

но если есть сомнения, используй просто GetLocaleInfo

Цитата(GetLocaleInfo @ MSDN)

Requirements
  Windows NT/2000/XP/Vista: Included in Windows Vista and later.
  Windows 95/98/Me: Unsupported.
  Header: Declared in Winnls.h; include Windows.h.
  Library: Use Kernel32.lib.


Цитата(GetLocaleInfoEx @ MSDN)

Requirements
  Windows NT/2000/XP/Vista: Included in Windows Vista and later.
  Windows 95/98/Me: Unsupported.
  Header: Declared in Winnls.h; include Windows.h.
  Library: Use Kernel32.lib.


в онлайне:

Цитата(GetLocaleInfo @ MSDN(online))

Requirements
Minimum supported client    Windows 2000 Professional
Minimum supported server    Windows 2000 Server
Header    Winnls.h (include Windows.h)
Library    Kernel32.lib
DLL    Kernel32.dll
Unicode and ANSI names    GetLocaleInfoW (Unicode) and GetLocaleInfoA (ANSI)

Цитата(GetLocaleInfoEx @ MSDN(online))

Requirements
Minimum supported client    Windows Vista
Minimum supported server    Windows Server 2008
Header    Winnls.h (include Windows.h)
Library    Kernel32.lib
DLL    Kernel32.dll


Добавлено через 2 минуты и 38 секунд
Цитата(GremlinProg @  2.6.2009,  15:31 Найти цитируемый пост)
вообще-то она даже в XP присутствует,

а, нет, перепутал
все верно - доступна только GetLocaleInfo


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
vns955
Дата 2.6.2009, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 21.11.2006

Репутация: нет
Всего: нет



Ну я пробовал использовать GetLocaleInfo() с флагом LOCALE_IDEFAULTCODEPAGE, она вернула 850. Я это значение подставил в setlocale() только с точкой т.е ".850" и то же самое :(.  Мне кажется что не этом дело - пробовал я различные значения, нужно наверное копать в другую сторону.
PM MAIL   Вверх
GremlinProg
Дата 2.6.2009, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(vns955 @  2.6.2009,  17:41 Найти цитируемый пост)
Ну я пробовал использовать GetLocaleInfo() с флагом LOCALE_IDEFAULTCODEPAGE, она вернула 850. Я это значение подставил в setlocale() только с точкой т.е ".850" и то же самое

как так-то?
Код

    int buffer    = 0;
    ::GetLocaleInfo(
        ::GetUserDefaultLCID(),
        LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE,
        (LPTSTR)&buffer,
        sizeof(buffer)
    );

Код

buffer == 1251

Код

    int buffer    = 0;
    ::GetLocaleInfo(
        ::GetUserDefaultLCID(),
        LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTCODEPAGE,
        (LPTSTR)&buffer,
        sizeof(buffer)
    );

Код

buffer == 866



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
GremlinProg
Дата 2.6.2009, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



уэльский:
Код

    int oem = 0,ansi = 0;
    LCID lcid    = MAKELCID( MAKELANGID(LANG_WELSH,SUBLANG_WELSH_UNITED_KINGDOM), SORT_DEFAULT);
    ::GetLocaleInfo(lcid,LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE,(LPTSTR)&ansi,sizeof(ansi));
    ::GetLocaleInfo(lcid,LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTCODEPAGE,(LPTSTR)&oem,sizeof(oem));

Код

oem = 850
ansi = 1252

чешский:
Код

    int oem = 0,ansi = 0;
    LCID lcid    = MAKELCID( MAKELANGID(LANG_CZECH,SUBLANG_CZECH_CZECH_REPUBLIC), SORT_DEFAULT);
    ::GetLocaleInfo(lcid,LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE,(LPTSTR)&ansi,sizeof(ansi));
    ::GetLocaleInfo(lcid,LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTCODEPAGE,(LPTSTR)&oem,sizeof(oem));

Код

oem = 852
ansi = 1250




--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
vns955
Дата 2.6.2009, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 21.11.2006

Репутация: нет
Всего: нет



Ну да, именно так если использовать такие ф-ции как у Вас, но я юзал GetSystemDefaultLCID() для затравки, поэтому получил другие значения, но это ничего не меняет - все равно не выводит правильно :(
PM MAIL   Вверх
GremlinProg
Дата 2.6.2009, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



с GetSystemDefaultLCID аналогично (у меня они равны)

vns955, я так полагаю, у тебя просто операционка на русскую локаль не настроена (смотри панель управления, язык и рег. стандарты и т.д.)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
vns955
Дата 2.6.2009, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 21.11.2006

Репутация: нет
Всего: нет



Проблема не в том чтоб русские символы выводить а чтоб правильно выводить другие, вот такой код неправильно выводит немецкие символы:

Код

   setlocale(LC_ALL, ".850");
   std::wcout.imbue(std::locale(".850"));
    //SetConsoleCP(lcid);

   wstring sStr = _T("Qualitätsprüfung");
   wcout << sStr.c_str() << endl;

Немецкий в системе установлен, установлено чтоб использавать этот язык для не юникод символов. Far и Total Commander корректно отображает немецкие папки - русские нет, а если я установлю по-умолчанию русский - будет наоборот. Так вот мне надо чтоб моя прога работала так же :(
PM MAIL   Вверх
GremlinProg
Дата 2.6.2009, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(vns955 @  2.6.2009,  21:29 Найти цитируемый пост)
 вот такой код неправильно выводит немецкие символы

перед setlocale попробуй поставить SetThreadLocale( lcid )


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0569 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.