Русский язык в консоли

Тема в разделе "LANGS.C", создана пользователем Praetor11, 29 окт 2009.

  1. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    А куда мы денемся? Если это правильно? =)))

    ЗЫ: (аналогия) у меня заложен нос, температура и головная боль. Гриппферон и деринат не катят (фигня отстойная), на антибиотики у меня аллергия, аспирин вреден для желудка, анальгин действует только с димедролом - а димедрола нет в нашей аптеке. Есть какие-то пилюли на "А", но они стоят под 200 за пачку, мне такого тоже не надо. Давайте решим раз и навсегда гадкую проблему респираторных заболеваний? Только умоляю, не парацетамол - это всем известная и черезодноместовая фигня, хотя и помогает, и все знают, но не хочу!
     
  2. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    Если нельзя юзать user32.dll (хотя, автор темы довольно странно ставит вопрос, консоль - не натив) Напишите аналог CharToOem, см. мой пост #16. В чем проблема-то?
     
  3. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Автор ставит вопрос так, как считает нужным. Потому что если бы он был у меня сформулирован иначе - гугл бы знал на него ответ и данная тема никогда не была бы создана. Если вы не знаете ответа на вопрос - просто ничего не пишите.

    Теперь по существу дела.
    CharToOEM не является правильным решением как многие из вас думают. Консоль поддерживает вывод русских символов, да ей в общем то вобще по барабану какой символ она выводит. При выводе её волнуют лишь два вопроса: в какой кодировке брать текст из экранного буфера, и какой шрифт для неё установлен. Что интересно, шрифт принадлежит именно экранному буферу консоли(!!) в то время как кодовая страница - консольному окну, связанному с процессом. В общем то проблема сводится к выбору необходимого шрифта консоли, и практика показывает что это Lucida Console. Но, к сожалению, отличное решение вопроса существует только под Vista (SetCurrentConsoleFontEx), в котором данный шрифт точно указывается в виде семейства шрифтов 54. Под ХП такое решение тоже есть в виде SetConsoleFont( ScreenBuffer, 6 ); Но цифорку 6 нужно менять от версии к версии..(даже на разных паках ХП она разная).

    Но в общем виде думаю копать надо от этого:
    Код (Text):
    1. extern "C" int main ()
    2. {
    3.    HANDLE mod = GetModuleHandleA("kernel32.dll");
    4.    BOOL (*SetConsoleFont)(HANDLE, int);
    5.    SetConsoleFont = (BOOL (*) (HANDLE,int))GetProcAddress(mod, "SetConsoleFont");
    6.    
    7.    SetConsoleCP (1251);
    8.    SetConsoleOutputCP (1251);
    9.    SetConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE),6);
    10.  
    11.    printf("Вася дурак\n");
    12.    getch();
    13. }
    Но со шрифтом тут явно что-то не то...Работает это только если хотя бы раз включить Lucida, видимо что системная таблица консольных цветов мб не одна, а по одной на Lucida и на растровый шрифт. Тут надо трудитца..
     
  4. SoftCreator

    SoftCreator New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2010
    Сообщения:
    36
    А вот разрешите предложить мое решение этой проблемы: http://softcreator.livejournal.com/594.html.
    Там внутри есть ссылка на h-файл, который эти проблемы решает. Заодно результаты копания с отладчиком в недрах CRT, может, кому и интересно будет. Если вкратце, это перехват WriteFile и прозрачный вызов CharToOem.
     
  5. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    Код (Text):
    1. setlocale (LC_ALL, NULL);
    upd. ах, да, есть ещё один способ: можно сорец хранить в кодировке cp866 -- для строковых литералов это сработает на все 100%.
     
  6. SoftCreator

    SoftCreator New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2010
    Сообщения:
    36
    Попробовал setlocale(LC_ALL, NULL):
    Код (Text):
    1. #include <stdio.h>
    2. #include <locale.h>
    3. #include "ruconsole.h"
    4.  
    5. void test_char()
    6. {
    7.     char buffer[100];
    8.     printf("Тест функций char.\n");
    9.     printf("Введите строку: ");
    10.     gets(buffer);
    11.     printf("Введенная строка: %s\n\n", buffer);
    12. }
    13.  
    14. void test_unicode()
    15. {
    16.     wchar_t buffer[100];
    17.     wprintf(L"Тест функций unicode.\n");
    18.     wprintf(L"Введите строку: ");
    19.     _getws(buffer);
    20.     wprintf(L"Введенная строка: %s\n\n", buffer);
    21. }
    22.  
    23. void main()
    24. {
    25.     //russian_console();
    26.     setlocale(LC_ALL, NULL);
    27.     test_char();
    28.     test_unicode();
    29. }
    Виста, получается вот что:
    Код (Text):
    1. ╥хёЄ ЇєэъЎшщ char.
    2. ┬тхфшЄх ёЄЁюъє:
     
  7. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    исходник в какой кодировке?
     
  8. SoftCreator

    SoftCreator New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2010
    Сообщения:
    36
    1251, само собой
     
  9. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    можно и так
    Код (Text):
    1. ostream& operator<<(ostream &o, const char *s){
    2.     char *str = new char[strlen(s)+1];
    3.     strcpy(str, s);
    4.     CharToOem(str, str);
    5.     printf("%s", str);
    6.     delete []str;
    7.     return o;
    8. }
    9.  
    10. int main(){
    11.     cout<<" Чуть помедленнее кони, чуть помедленнее! \n"
    12.           " Умоляю вас вскачь не лететь! \n"
    13.           " Но что-то кони мне достались привередливые, \n"
    14.           " Коль дожить не успел, так хотя бы допеть! "<<'\n';
    15. }
     
  10. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    SoftCreator

    у меня работает
    _tsetlocale(LC_ALL, _T(".1251"));

    ну и компилим в Unicode само собой
     
  11. SoftCreator

    SoftCreator New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2010
    Сообщения:
    36
    А вот мой вариант работает и в Unicode, и в char :P
    С юникодом вообще очень приятно работать
     
  12. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    #include <locale.h>
    возможно должно быть выше

    #include <locale.h>
    #include <windows.h>
    #include <tchar.h>
    #include <stdio.h>
     
  13. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    SoftCreator

    мой тоже ;)
    но возможно с ansi char будут проблемы в нерусских виндах
     
  14. SoftCreator

    SoftCreator New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2010
    Сообщения:
    36
    Ну не знаю... Я наткнулся вот на какую вещь - если в консоли используется растровый шрифт, нужно выводить ansi-строки в 866 кодировке, иначе будут крякозябры. Поэтому я и хукал WriteFile с преобразованием CharToOemBuff.
     
  15. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    SoftCreator
    Я имел ввиду что мой сорц компилится в юникод или ansi по необходимости.

    Код (Text):
    1. void _tmain(int argc, _TCHAR* argv[])
    2. {
    3.     _TCHAR   Buffer[MAX_PATH_SIZE];
    4.     _TCHAR*  DirPath;
    5.  
    6.     _tsetlocale(LC_ALL, _T(".1251"));
    7.  
    8.     if ( argc != 2 )
    9.     {
    10.         _tprintf(_T("\nUsage: ParseDir <DirPath>\n"));
    11.         return;
    12.     }
    13.  
    14.     DirPath = argv[1];
    15.     // skip starting quotation mark
    16.     if ( *DirPath == _T('"') )
    17.         DirPath++;
    18.  
    19. #ifdef _UNICODE
    20.     // We must use the \\?\ notation for the path in order to bypass
    21.     // the Win32 path length limitation of 260 chars
    22.     _tcscpy(Buffer, _T("\\\\?\\"));
    23.     _tcscat(Buffer, DirPath);
    24. #else
    25.     _tcscpy(Buffer, DirPath);
    26. #endif
    27.  
    28.     size_t len = _tcslen(Buffer);
    29.  
    30.     // erase ending quotation mark
    31.     if ( Buffer[len-1] == _T('"') )
    32.     {
    33.         Buffer[len-1] = _T('\0');
    34.         len--;
    35.     }
    36.  
    37.     if ( Buffer[len-1] == _T('\\') )
    38.         Buffer[len-1] = _T('\0');
    39.  
    40.     _tprintf(_T("\nProcessing...\n"));
    41.  
    42.     ProcessFilesInDirectoryTree(Buffer);
    43.  
    44.     _tprintf(_T("files: %d modified: %d\r"), files, modified);
    45.     _tprintf(_T("\nDone!\n"));
    46. }
     
  16. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    osox
    Оригинально :)
     
  17. SoftCreator

    SoftCreator New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2010
    Сообщения:
    36
    А что не так? По-другому и нельзя
     
  18. SoftCreator

    SoftCreator New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2010
    Сообщения:
    36
    А в ansi и с растровыми шрифтами показывает русский? Какая винда?
     
  19. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    SoftCreator
    Ну возвращать "о" вместо 0 ;)

    Я так глубоко не экспериментировал, сейчас что-то даже не соображу какие это растровые %)
    Хотя в данном случае если пользователь через ярлык выставил какие-то кривые шрифты то он
    ССЗБ, в консоли по дефолту все нормально должно быть.
     
  20. SoftCreator

    SoftCreator New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2010
    Сообщения:
    36
    Эээээ... Вернуть 0, там где нужна ссылка, это круто :)
    А вообще, оператор вывода в поток должен возвращать ссылку на экземпляр потока, чтобы можно было писать строки типа cout << one << two << three << endl;

    Ну даже не знаю... Моя виста крякозябры показывает со стандартным шрифтом, который не Lucida Console