А куда мы денемся? Если это правильно? =))) ЗЫ: (аналогия) у меня заложен нос, температура и головная боль. Гриппферон и деринат не катят (фигня отстойная), на антибиотики у меня аллергия, аспирин вреден для желудка, анальгин действует только с димедролом - а димедрола нет в нашей аптеке. Есть какие-то пилюли на "А", но они стоят под 200 за пачку, мне такого тоже не надо. Давайте решим раз и навсегда гадкую проблему респираторных заболеваний? Только умоляю, не парацетамол - это всем известная и черезодноместовая фигня, хотя и помогает, и все знают, но не хочу!
Если нельзя юзать user32.dll (хотя, автор темы довольно странно ставит вопрос, консоль - не натив) Напишите аналог CharToOem, см. мой пост #16. В чем проблема-то?
Автор ставит вопрос так, как считает нужным. Потому что если бы он был у меня сформулирован иначе - гугл бы знал на него ответ и данная тема никогда не была бы создана. Если вы не знаете ответа на вопрос - просто ничего не пишите. Теперь по существу дела. CharToOEM не является правильным решением как многие из вас думают. Консоль поддерживает вывод русских символов, да ей в общем то вобще по барабану какой символ она выводит. При выводе её волнуют лишь два вопроса: в какой кодировке брать текст из экранного буфера, и какой шрифт для неё установлен. Что интересно, шрифт принадлежит именно экранному буферу консоли(!!) в то время как кодовая страница - консольному окну, связанному с процессом. В общем то проблема сводится к выбору необходимого шрифта консоли, и практика показывает что это Lucida Console. Но, к сожалению, отличное решение вопроса существует только под Vista (SetCurrentConsoleFontEx), в котором данный шрифт точно указывается в виде семейства шрифтов 54. Под ХП такое решение тоже есть в виде SetConsoleFont( ScreenBuffer, 6 ); Но цифорку 6 нужно менять от версии к версии..(даже на разных паках ХП она разная). Но в общем виде думаю копать надо от этого: Код (Text): extern "C" int main () { HANDLE mod = GetModuleHandleA("kernel32.dll"); BOOL (*SetConsoleFont)(HANDLE, int); SetConsoleFont = (BOOL (*) (HANDLE,int))GetProcAddress(mod, "SetConsoleFont"); SetConsoleCP (1251); SetConsoleOutputCP (1251); SetConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE),6); printf("Вася дурак\n"); getch(); } Но со шрифтом тут явно что-то не то...Работает это только если хотя бы раз включить Lucida, видимо что системная таблица консольных цветов мб не одна, а по одной на Lucida и на растровый шрифт. Тут надо трудитца..
А вот разрешите предложить мое решение этой проблемы: http://softcreator.livejournal.com/594.html. Там внутри есть ссылка на h-файл, который эти проблемы решает. Заодно результаты копания с отладчиком в недрах CRT, может, кому и интересно будет. Если вкратце, это перехват WriteFile и прозрачный вызов CharToOem.
Код (Text): setlocale (LC_ALL, NULL); upd. ах, да, есть ещё один способ: можно сорец хранить в кодировке cp866 -- для строковых литералов это сработает на все 100%.
Попробовал setlocale(LC_ALL, NULL): Код (Text): #include <stdio.h> #include <locale.h> #include "ruconsole.h" void test_char() { char buffer[100]; printf("Тест функций char.\n"); printf("Введите строку: "); gets(buffer); printf("Введенная строка: %s\n\n", buffer); } void test_unicode() { wchar_t buffer[100]; wprintf(L"Тест функций unicode.\n"); wprintf(L"Введите строку: "); _getws(buffer); wprintf(L"Введенная строка: %s\n\n", buffer); } void main() { //russian_console(); setlocale(LC_ALL, NULL); test_char(); test_unicode(); } Виста, получается вот что: Код (Text): ╥хёЄ ЇєэъЎшщ char. ┬тхфшЄх ёЄЁюъє:
можно и так Код (Text): ostream& operator<<(ostream &o, const char *s){ char *str = new char[strlen(s)+1]; strcpy(str, s); CharToOem(str, str); printf("%s", str); delete []str; return o; } int main(){ cout<<" Чуть помедленнее кони, чуть помедленнее! \n" " Умоляю вас вскачь не лететь! \n" " Но что-то кони мне достались привередливые, \n" " Коль дожить не успел, так хотя бы допеть! "<<'\n'; }
#include <locale.h> возможно должно быть выше #include <locale.h> #include <windows.h> #include <tchar.h> #include <stdio.h>
Ну не знаю... Я наткнулся вот на какую вещь - если в консоли используется растровый шрифт, нужно выводить ansi-строки в 866 кодировке, иначе будут крякозябры. Поэтому я и хукал WriteFile с преобразованием CharToOemBuff.
SoftCreator Я имел ввиду что мой сорц компилится в юникод или ansi по необходимости. Код (Text): void _tmain(int argc, _TCHAR* argv[]) { _TCHAR Buffer[MAX_PATH_SIZE]; _TCHAR* DirPath; _tsetlocale(LC_ALL, _T(".1251")); if ( argc != 2 ) { _tprintf(_T("\nUsage: ParseDir <DirPath>\n")); return; } DirPath = argv[1]; // skip starting quotation mark if ( *DirPath == _T('"') ) DirPath++; #ifdef _UNICODE // We must use the \\?\ notation for the path in order to bypass // the Win32 path length limitation of 260 chars _tcscpy(Buffer, _T("\\\\?\\")); _tcscat(Buffer, DirPath); #else _tcscpy(Buffer, DirPath); #endif size_t len = _tcslen(Buffer); // erase ending quotation mark if ( Buffer[len-1] == _T('"') ) { Buffer[len-1] = _T('\0'); len--; } if ( Buffer[len-1] == _T('\\') ) Buffer[len-1] = _T('\0'); _tprintf(_T("\nProcessing...\n")); ProcessFilesInDirectoryTree(Buffer); _tprintf(_T("files: %d modified: %d\r"), files, modified); _tprintf(_T("\nDone!\n")); }
SoftCreator Ну возвращать "о" вместо 0 Я так глубоко не экспериментировал, сейчас что-то даже не соображу какие это растровые %) Хотя в данном случае если пользователь через ярлык выставил какие-то кривые шрифты то он ССЗБ, в консоли по дефолту все нормально должно быть.
Эээээ... Вернуть 0, там где нужна ссылка, это круто А вообще, оператор вывода в поток должен возвращать ссылку на экземпляр потока, чтобы можно было писать строки типа cout << one << two << three << endl; Ну даже не знаю... Моя виста крякозябры показывает со стандартным шрифтом, который не Lucida Console