Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Вывод кириллицы в консоли

281
31 мая 2012 года
Fan][
279 / / 19.12.2003
Пробую вывести тесте в консоли в кириллице наиболее простым и универсальным способом (без написания дополнительных функций)- ничего не получается. Перепробоавл все известные мне способы:

 
Код:
system("chcp 1251 > nul");

 
Код:
setlocale(LC_ALL, "Russian");
ничего не получается.
277
31 мая 2012 года
arrjj
1.7K / / 26.01.2011
В чем проект написан/собираешь?

Наиболее простой способ - изменить кодировку исходников (например в редакторе notepad++ editpad и т.д.).
281
31 мая 2012 года
Fan][
279 / / 19.12.2003
Цитата: arrjj
В чем проект написан/собираешь?


Проект полностью создается в Dev-C++ 5.2.0.0. Пытался делать его в Юникод, но не нашёл в Dev-C++ такой возможности.

Цитата: arrjj
Наиболее простой способ - изменить кодировку исходников (например в редакторе notepad++ editpad и т.д.).


Это я знаю, но гимор то какой!
Это если пару десятков строк - ещё куда не шло

326
31 мая 2012 года
sadovoya
757 / / 19.11.2005
У меня setlocale() в Code::Blocks работат, как для исходников в Windows-1251, так и для UTF-8. В последнем случае приходится еще писать wcout вместо cout и строки "широкие" использовать (с L перед кавычками). Все работает, но только на вывод в консоль, а на ввод с консоли приходится конвертировать апишками OemToChar() и OemToCharW(). Нет ли способа проще для ввода русских букв?
281
31 мая 2012 года
Fan][
279 / / 19.12.2003
Цитата: sadovoya
У меня setlocale() в Code::Blocks работат, как для исходников в Windows-1251, так и для UTF-8. В последнем случае приходится еще писать wcout вместо cout и строки "широкие" использовать (с L перед кавычками). Все работает, но только на вывод в консоль, а на ввод с консоли приходится конвертировать апишками OemToChar() и OemToCharW().


Жутко гиморно. Пробовал уже. Это когда пару тройку строк надо - нормально, конечно.
Я то конечно отдельной цункцией пользуюсь, но рано или поздно это может привести к какому-нибудь косяку. Хотелось бы чтобы без фантазий. И, даже кажется, был такой способ, но вспомнить не могу.
А проблем с вводом русских букв у меня нет. Или имеется ввод и запись куда-нибудь?

326
31 мая 2012 года
sadovoya
757 / / 19.11.2005
Нет, просто, если я в таком коде:

Код:
//Кодировка win1251

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

/*
   OemToChar() для возвращаемого из cin
*/


using namespace std;

int main()
{
    setlocale(0, "rus");

    char str[80];
   
    cout << "Введите строку\n";

    cin >> str;
   
    OemToChar(str, str);
   
    cout << "Введена str: " << str << endl;
   
    return 0;
}
уберу OemToChar, то перековеркается вывод последний.

А Вам может поможет материал с этого сайта, где обсуждалась эта проблема (здесь). Возможно у Вас сработает ф-ция SetConsoleCP(1251).
2.1K
31 мая 2012 года
disputant
95 / / 28.05.2007
Тут вот тоже имеет место дискуссия на эту тему.
326
31 мая 2012 года
sadovoya
757 / / 19.11.2005
Заработало! И ввод и вывод. Но только для Utf-8. С win1251 отпал даже вывод :). Для юникод:

Код:
//Codec for this source is UTF-8

#include <iostream>

using namespace std;
int main() {
    setlocale(LC_ALL, ".OCP");
    wchar_t prompt[21] = L"Введите строку...";
    wstring wstr;
    wcout << prompt << endl;
    wcin >> wstr;
    wcout << L"Введено: " << wstr;

    return 0;
}
Т.е. вместо "rus" в setlocale передаем ".OCP". Помогла ссылка disputant - спасибо!
326
31 мая 2012 года
sadovoya
757 / / 19.11.2005
Методом "тыка" удалось и Win1251 победить:


Код:
//Codec for this source is Win1251

#include <iostream>

using namespace std;
int main() {
    setlocale(LC_ALL, ".OCP");
    char prompt[21] = "Введите строку...";
    wstring str;
    wcout << prompt << endl;
    wcin >> str;
    wcout << "Введено: " << str;

    return 0;
}
281
01 июня 2012 года
Fan][
279 / / 19.12.2003
А у меня в этом коде:


 
Код:
#include <iostream>
#include <clocale> //для std::setlocale()

int main()
{
   std::setlocale(LC_ALL, "");
   std::wcout << L"Привет, мир!" << std::endl;
}
Dev-C++ выдаёт ошибки в 7 строке:
Цитата:

[Error] Illegal byte sequence
Error 1 (if this is the only error: please check your library includes)


Почему?

326
01 июня 2012 года
sadovoya
757 / / 19.11.2005
Думаю, из-за кодировки исходника. Мне Code::Blocks тоже ругает "широкие" русские строки (L"русская строка"), если кодирую исходник в Windows-1251. Точно такое сообщение об ошибке, как у вас. C UTF-8 не ругается.
281
01 июня 2012 года
Fan][
279 / / 19.12.2003
Цитата: sadovoya
Думаю, из-за кодировки исходника. Мне Code::Blocks тоже ругает "широкие" русские строки (L"русская строка"), если кодирую исходник в Windows-1251. Точно такое сообщение об ошибке, как у вас. C UTF-8 не ругается.


А как Вы в Code::Blocks в UTF переводите?
Хотя, конечно, это гиморно очень. GCC что-то ни один способ, кроме написания отдельной функции, не принимает. А хочется универсальности под любой компилятор и поменьше букововк в коде

326
01 июня 2012 года
sadovoya
757 / / 19.11.2005
В Code::Blocks это очень просто - EDIT->File Encoding->UTF-8. А чтобы сделать по-умолчанию для всех проектов - SETTINGS->EDITOR->GENERAL SETTINGS и там во вкладках ищем выбор кодировки. Мне посложней, хочу еще и однообразия для винды и линукса.
281
02 июня 2012 года
Fan][
279 / / 19.12.2003
Так вот и я хочу единообразно и под любые компиляторы и системы
1
02 июня 2012 года
kot_
7.3K / / 20.01.2000
Цитата: Fan][
Так вот и я хочу единообразно и под любые компиляторы и системы


единообразно изкаропки это не будет.
Если такое нужно - значит надо пользоваться допбиблиотеками - например Qt

326
02 июня 2012 года
sadovoya
757 / / 19.11.2005
Да, в кьют этих проблем нет. Рад, что именно ее упомянули, я к ней неравнодушен :) Отличная штука.
281
17 сентября 2014 года
Fan][
279 / / 19.12.2003
Освежу темку то.

Нормально всё "кириллизуется" через использование setlocale(LC_ALL, ".OCP") и std::wcout.
Но вот есть строка
const string x = = "Привет, " + name + "!";
, на которой этот вроде бы рабочий костыль вылетает (т.е. выводятся опять кракозябры). Т.е.
std::wcout << x;
не выводит кириллицы.
Что-нибудь несложное можно придумать?
412
17 сентября 2014 года
grgdvo
323 / / 04.07.2007
Может std::wstring поможет??
281
17 сентября 2014 года
Fan][
279 / / 19.12.2003
Цитата: grgdvo
Может std::wstring поможет??


Да нет - не помогло :(

281
17 сентября 2014 года
Fan][
279 / / 19.12.2003
Вобщем, вот такое решение подсказывает коллективный разум (вроде работает всегда и везде). Т.е. полностью сплагиаченный код:

Код:
#include <iostream>
#include <stdexcept>
#include <windows.h>
#include <string>
#include <vector>

using namespace std;


// Перекодировщики из cp1251 в 866 и обратно функциями WinAPI: CharToOem() и OemToChar()
namespace details {

template<class Func>
inline std::string converter(const std::string &text, Func func)
{
    std::vector<char> buffer(text.size() + 1);
    if ( !func(text.c_str(), &buffer[0]) )
        throw std::runtime_error("Invalid character");
    return std::string(buffer.begin(), buffer.end() - 1);
}

}

//namespace details

std::string ansiFromOem(const std::string &text)
{
    return ::details::converter(text, &OemToCharA);
}

std::string oemFromAnsi(const std::string &text)
{
    return ::details::converter(text, &CharToOemA);
}

int main()
{
    string name;
    cout << oemFromAnsi ("Введите Ваше имя: ");
    cin >> name;
    cout << endl;

// Если name не обработать с помощью ansiFromOem, то значение name отобразится кракозябрами
    string greeting = "Привет, " + ansiFromOem(name) + "!";
    cout << oemFromAnsi(greeting);
    return 0;
}
Проверьте - может какие косяки будут
326
25 января 2015 года
sadovoya
757 / / 19.11.2005
Да вроде и так все работает. Исходник в Utf-8, setlocale(LC_ALL, ".OCP), "широкие" строки , w-варианты cout, cin и string. И ф-ции "си-шные" в w-вариантах. Вот пример на все это:

Код:
//Codec for this source is UTF-8

#include <iostream>
#include <cstdio>
#include <clocale>
#include <string>

using namespace std;

int main() {

    setlocale(LC_ALL, ".OCP");

    wchar_t prompt[] = L"Введите слово: ";
    wstring wstr;
    wcout << prompt;
    wcin >> wstr;
    wcout << L"Введено: " << wstr << endl << endl;

    wstring wstr1 = L"Введите ваше имя: ";
    wcout << wstr1;
    wstring n;
    wcin >> n;
    wstring ans = L"Привет, " + n + L"!";
    wcout << ans << endl << endl;

    wchar_t str [80];
    wprintf (L"Введите слово: ");
    wscanf (L"%s", str);
    wprintf (L"Введено: %s\n", str);

    return 0;
}
326
26 января 2015 года
sadovoya
757 / / 19.11.2005
Будет работать и в Linux, если вместо setlocale(LC_ALL, ".OCP") написать setlocale(LC_ALL, "") (установка системной локали). Можно вообще сделать код универсальным через условную компиляцию. Вроде такого:

Код:
#define LINUX_CON //если Линукс.

using namespace std;

int main() {
    #ifdef LINUX_CON
        setlocale(LC_ALL, ""); //системная
    #else
        setlocale(LC_ALL, ".OCP");//OEM
    #endif
.........
и т.д.,как ранее
Исходник в UTF-8 использовал.
326
11 мая 2015 года
sadovoya
757 / / 19.11.2005
Насчет:
 
Код:
system("chcp 1251 > nul");
Работает, если шрифт у консоли установлен в Lucida Console.
То же верно и для использования такой русификации:
 
Код:
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
Вот пара рабочих примеров (для Windows разумеется):
Код:
//Кодировка файла Windows-1251
#include <windows.h>
#include <iostream>
#include <cstdio>

//При использовании функций настройки консоли русские буквы будут отображаться
//правильно, если для консольного окна выбран шрифт Lucida Console. Для выбора
//шрифта нужно щелкнуть правой кнопкой мыши по заголовку окна, выполнить команду
//Свойства, а затем на вкладке  Шрифт выбрать нужный шрифт.

//По материалу статьи:
//"Локализация консольных приложений в языке С++" В.Л.Тарасов

using namespace std;

int main() {
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    char Name[100];
    cout << "Имя: ";
    cin >> Name;
    cout << "Привет, " << Name << endl;

    printf("Имя: ");
    scanf("%s", Name);
    printf("Привет, %s\n", Name);

    getchar();

}
Код:
//Кодировка файла Windows-1251
//Работает, если шрифт в консоли Lucida Console
#include <iostream>
#include <cstdlib> //для system
#include <cstdio>

using namespace std;

int main()
{
    system("chcp 1251 > nul");
    char str[200];
    cout << "Имя: ";
    cin >> str;
    cout << "Привет, " << str << endl;
    printf("Имя: ");
    scanf("%s", str);
    printf("Привет, %s\n", str);
    getchar();
    return 0;
}
Способы так себе... Не кросс-платформенные и еще шрифт надо менять.
7
15 мая 2015 года
@pixo $oft
3.4K / / 20.09.2006
А как быть, когда шрифт не Lucida Console? setlocale() же как-то без этого справляется.
Хотелось бы знать механизм её работы.

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог