Модераторы: Daevaorn
  

Поиск:

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


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Если я плохо искал, и это уже где-то и когда-то было - просьба не пинать smile
Под влиянием регулярно возникающих на форумах вопросов а-ля "у меня на C++ в консоли вместо кириллицы выводятся кракозябы", взялся за написание велосипеда, исправляющего (?) ситуацию для iostreams. Решение очевидно: codecvt facet. Просьба посмотреть и указать потенциальные грабли.
Код

// concodecvt.hpp

#include <locale>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#pragma comment(lib, "user32")

class con_codecvt : public std::codecvt<char, char, mbstate_t> {
public:
    explicit con_codecvt(size_t r = 0) : std::codecvt<char, char, mbstate_t>(r) { }
protected:
    result do_in(mbstate_t&,
                 const char *from, const char *from_end, const char *&from_next,
                 char *to, char *to_end, char *&to_next) const {
        ptrdiff_t t = min(from_end - from, to_end - to);
        OemToCharBuffA(from, to, t);
        from_next = from + t;
        to_next = to + t;
        return ok;
    }
    result do_out(mbstate_t&,
                  const char *from, const char *from_end, const char *&from_next,
                  char *to, char *to_end, char *&to_next) const {
        ptrdiff_t t = min(from_end - from, to_end - to);
        CharToOemBuffA(from, to, t);
        from_next = from + t;
        to_next = to + t;
        return ok;
    }
    result do_unshift(mbstate_t&, char *to, char *to_end, char *&to_next) const {
        to_next = to_end;
        return ok;
    }
    int do_encoding() const throw() {
        return 1;
    }
    bool do_always_noconv() const throw() {
        return false;
    }
    int do_length(const mbstate_t&,
                  const char *from, const char *from_end, size_t max) const {
        return std::codecvt<char, char, mbstate_t>::do_length
            (mbstate_t(), from, from_end, max);
    }
};


Использование тривиально, например:
Код

#include <iostream>
#include <fstream>
#include <string>
#include "concodecvt.hpp"

using namespace std;

int main() {
    locale conlocale(locale(), new con_codecvt);
    string filename, str;
    cin.imbue(conlocale);
    cout.imbue(conlocale);
    cout << "Привет, мир!\n";
    cout << "Введите имя файла:\n";
    getline(cin, filename);
    cout << "Введите строку:\n";
    getline(cin, str);
    ofstream ofs(filename.c_str());
    if (!ofs) {
        cerr << "Не могу открыть файл " << filename << "\n";
        return 1;
    }
    ofs << str;
    return 0;
}



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Fighter
Дата 12.5.2005, 05:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



У меня одни ошибки выдает.
PM MAIL   Вверх
ABPOPA
Дата 12.5.2005, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



мне почему-то так легче
Код

char bufRus[256];

char* Rus(const char* text)
{
    CharToOem(text,bufRus);
    return bufRus;
}

пример прост
Код

cout<<(Rus("Меню:"));

PM   Вверх
srd
Дата 12.5.2005, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


Профиль
Группа: Участник Клуба
Сообщений: 951
Регистрация: 30.8.2003
Где: Владивосток

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



А может проще сразу исходники в кодировке DOS866 набирать? А то на каждый вывод вызывать функцию конвертирования - накладно что-то получается...


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
Void
Дата 12.5.2005, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Цитата(Fighter @ 12.5.2005, 07:03)
У меня одни ошибки выдает.

При компиляции или при выполнении? Какой компилятор, ОС?


Цитата(srd @ 12.5.2005, 14:40)
А может проще сразу исходники в кодировке DOS866 набирать? А то на каждый вывод вызывать функцию конвертирования - накладно что-то получается...

А плюсовые потоки сами по себе небыстрая вещь smile И что это за приложение, которое большую часть времени тратит на консольный ввод/вывод...

Мне просто захотелось показать идеологически правильное (наверное) решение проблемы. Не зря же в стандарт ввели эту фичу smile


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
AISIN
Дата 12.5.2005, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(Void @ 12.5.2005, 19:07)
Цитата(Fighter @ 12.5.2005, 07:03)
У меня одни ошибки выдает.

При компиляции или при выполнении? Какой компилятор, ОС?



У меня Visual копирую твой листинг. Компилирую одни ошибки! Набираю все тоже самое руками и все без ошибок!
--------------------
Внимание!!! Внимание!!!Запущена программа по завоеванию мира!!!Выполненно 0,000000000000000000000000000000000000000000000000000002%
PM MAIL   Вверх
Fighter
Дата 12.5.2005, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Void @ 12.5.2005, 19:07)
Цитата (Fighter @ 12.5.2005, 07:03)
У меня одни ошибки выдает.

При компиляции или при выполнении? Какой компилятор, ОС?



Цитата(AISIN @ 12.5.2005, 21:06)
Цитата (Void @ 12.5.2005, 19:07)
Цитата (Fighter @ 12.5.2005, 07:03)
У меня одни ошибки выдает.

При компиляции или при выполнении? Какой компилятор, ОС?



У меня Visual копирую твой листинг. Компилирую одни ошибки! Набираю все тоже самое руками и все без ошибок!


А ну теперь я понял фишку. Я пока что не набирал, но надеюсь, что будет работать. Дело в том, что кодировки тут и в Visual C++ различаются (скорее всего коды символов разные). Вот он и пишет что там какой-то символ неизвестен (если мне память не изменяет). В общем, на досуге все в ручную перепишу и попробую.

P.S. Наконец-то можно спокойно набирать в консоле программы (а не юзать для таких целей Turbo C++).
PM MAIL   Вверх
chaos
Дата 13.5.2005, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


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

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



Цитата(ABPOPA @ 12.5.2005, 12:16)
мне почему-то так легче
Код

char bufRus[256];

char* Rus(const char* text)
{
    CharToOem(text,bufRus);
    return bufRus;
}

пример прост
Код

cout<<(Rus("Меню:"));

а мне такое решение нравится))
Код

#include <windows.h>
#include <iostream>

using namespace std;

char buf[256];

ostream& operator<< (ostream& out, string& str) 
{
    CharToOem(str.c_str(), buf);
    out << buf;
    return out;
}

int main()
{
    cout << string("ÀàÁáÖö") << endl;
    return 0;
}

PM WWW   Вверх
En_t_end
Дата 13.5.2005, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Я вообще в фаре все для консоли делаю... а вообще надо просто в настройках студии подключить нужную кодировку для записи и просто менять её, когда надо писать в win.
PM MAIL ICQ Skype GTalk Jabber   Вверх
Fighter
Дата 13.5.2005, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(En_t_end @ 13.5.2005, 13:39)
Я вообще в фаре все для консоли делаю... а вообще надо просто в настройках студии подключить нужную кодировку для записи и просто менять её, когда надо писать в win.

Поподробнее
PM MAIL   Вверх
Void
Дата 13.5.2005, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Цитата(Fighter @ 13.5.2005, 01:08)
P.S. Наконец-то можно спокойно набирать в консоле программы (а не юзать для таких целей Turbo C++).

Буду очень рад, если это кому-нибудь поможет smile
Кстати, для повышения быстродействия можно переопределить еще один метод базового класса:
Код

    int do_maxlength() const throw() {
        return 1024;
    }

Я понадеялся на дефолтную реализацию, а она возвращает 1 - и перекодировка идет посимвольно. Вместо 1024 здесь можно определить любую достаточно большую константу - хоть INT_MAX.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
srd
Дата 28.5.2005, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


Профиль
Группа: Участник Клуба
Сообщений: 951
Регистрация: 30.8.2003
Где: Владивосток

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



А какое идеологически верное решение для CRT? Если программа пишется на "чистом" Си, например?


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

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


 




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


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

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