Форум программистов, компьютерный форум CyberForum.ru

Преобразование String UTF8 в 1251 - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.88
Tester64
394 / 355 / 43
Регистрация: 22.05.2013
Сообщений: 2,461
31.08.2014, 19:10     Преобразование String UTF8 в 1251 #1
Нашел пример:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
    wchar_t s[] = L"London Москва";
    char utf8[100];
    wchar_t wstr[100];
    char s1251[100];
    WideCharToMultiByte(CP_UTF8, 0, s, -1, utf8, 100, NULL, NULL);
    utf8[WideCharToMultiByte(CP_UTF8, 0, s, -1, utf8, 0, NULL, NULL)]='\0';
    // Подготовили строку UTF8 дальше идет ее преобразование в 1251
    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, 100);
    wstr[MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, 0)];
    WideCharToMultiByte(1251, 0, wstr, -1, s1251, 100, NULL, NULL);
    utf8[WideCharToMultiByte(1251, 0, wstr, -1, s1251, 0, NULL, NULL)]='\0';
    printf("%s\n", s1251);
Шикарно работает в консоли, но ОЧЕНЬ надо пределать его в функции со String
C++ (Qt)
1
2
3
4
5
std::string UTF8_to_1251(const std::string ss) {
   //...
}
...
printf(UTF8_to_1251("London Москва"));
Но знаний по преобразованию строк в char и назад не хватает! Только начал вычитывать, а функция нужна срочно!
Помогите хоть немножко!
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ryzhikov_A
6 / 6 / 0
Регистрация: 14.10.2012
Сообщений: 36
31.08.2014, 20:09     Преобразование String UTF8 в 1251 #2
Для перехода от string к const char* (неизменяемому массиву символов в куче) используйте метод c_str():
C++
1
const char* cLikeString = <объект типа string>.c_str();
Для создания строки типа string из массива символов просто вызовите конструктор.
C++
1
2
char* cLikeString = ...;
std::string cppLikeString(cLikeString );
Добавлено через 6 минут
p.s. Вы используете массивы символов на стеке (char arrayName[]). Вместо используемого выше варианта с указателями(char*) вполне можно использовать и их, синтаксис останется таким же. (вызов std::string(arrayName) эквивалентен std::string(&arrayName[0]), т.е. arrayName в данном случае приводится к char*)
Tester64
394 / 355 / 43
Регистрация: 22.05.2013
Сообщений: 2,461
31.08.2014, 21:04  [ТС]     Преобразование String UTF8 в 1251 #3
Вторая часть кода подошла, но не первая. Она работает, но мне нужно другое:
std::string (или std::wstring) в wchar_t
Ryzhikov_A
6 / 6 / 0
Регистрация: 14.10.2012
Сообщений: 36
31.08.2014, 21:22     Преобразование String UTF8 в 1251 #4
Аналогично
C++
1
2
std::wstring line(L"test string");
const wchar_t* szName = line.c_str();
DrOffset
6456 / 3830 / 885
Регистрация: 30.01.2014
Сообщений: 6,626
31.08.2014, 21:49     Преобразование String UTF8 в 1251 #5
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Tester64, тут еще ведь нужно понимать, что L"строка" - это не UTF8. Это скорее UTF16 или USC2, если рассматривать windows.
Конвертирование же именно UTF8 в CP1251 под windows можно так сделать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::string UTF8_to_CP1251(std::string const & utf8)
{
    if(!utf8.empty())
    {
        int wchlen = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.size(), NULL, 0);
        if(wchlen > 0 && wchlen != 0xFFFD)
        {
            std::vector<wchar_t> wbuf(wchlen);
            MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.size(), &wbuf[0], wchlen);
            std::vector<char> buf(wchlen);
            WideCharToMultiByte(1251, 0, &wbuf[0], wchlen, &buf[0], wchlen, 0, 0);
 
            return std::string(&buf[0], wchlen);
        }
    }
    return std::string();
}
Tester64
394 / 355 / 43
Регистрация: 22.05.2013
Сообщений: 2,461
31.08.2014, 22:25  [ТС]     Преобразование String UTF8 в 1251 #6
ИДЕАЛЬНО!
Правда прилось еще добавить
C++ (Qt)
1
#include <vector>
(я как новичок этого не знал)
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
01.09.2014, 01:47     Преобразование String UTF8 в 1251 #7
Хм, все бегут без оглядки от CP1251 и от всяких понаехавших "кодовых страниц", а тут наоборот, UTF-8 не нравится
DrOffset
6456 / 3830 / 885
Регистрация: 30.01.2014
Сообщений: 6,626
01.09.2014, 01:50     Преобразование String UTF8 в 1251 #8
Цитата Сообщение от gromo Посмотреть сообщение
Хм, все бегут без оглядки от CP1251, а тут наоборот, UTF-8 не нравится
Пусть сам налетает на все грабли
Всех все равно не переубедишь. Я тут сперва написал большой пост про пользу юникода и почему подстраиваться под устаревшую вин консоль (с дос кодировкой по умолчанию) не обязательно, но потом стер.
Tester64
394 / 355 / 43
Регистрация: 22.05.2013
Сообщений: 2,461
01.09.2014, 03:48  [ТС]     Преобразование String UTF8 в 1251 #9
Цитата Сообщение от gromo Посмотреть сообщение
Хм, все бегут без оглядки от CP1251 и от всяких понаехавших "кодовых страниц", а тут наоборот, UTF-8 не нравится
Цитата Сообщение от DrOffset Посмотреть сообщение
про пользу юникода и почему подстраиваться под устаревшую вин консоль (с дос кодировкой по умолчанию) не обязательно
Считайте капризом! Работаю под виндой. Пишу в блокноте (notepad++) без IDE. Компилирую батником. Код не большой. Самое главное - скорость сборки. А не удобство редактора и выпадающие подсказки. Результат вывожу в универсальную виндовую консоль. Как перепрошить всю винду с анси на юникод не знаю, да и не хочу - другие программы "крокозябры" писать будут (включая RAR и 7ZIP). Написал функцию - Rep("привет мир") - выводящую строку с результатом в консоль. В нее-же зашил анси. Все исходники (текстовики СРР и Н) храню в юникоде (где-то вычитал что это любимая кодировка g++ и NDK). Rep вызываю редко, но не хочу заморачиваться с перекодированием системной консоли на чужих машинах (или писать транслитом или вспоминать как это зовется на английском). Под линукс (если перейду) сделаю другой Rep. Под андроид третий (уже сделал). Команда одна, но сама решает что и как выводить. И главное без заморочек с кодировкой на входе. Смогу одной константой отключить перекодирование, но пока... Так удобнее! Да и учусь я пока. Простые утилитки пишу, базовые конструкции тестирую...

Пока-что перевод нужен был ТОЛЬКО для отладочных сообщений в консоль, хотя бывает необходимость и при работе с файлами кодировку заменить и со старым сервером через сеть пообщаться... Пусть себе лежит в коллекции. Заодно понял как строки конвертировать между разными типами (char-wchar-string), а это похоже крайне необохдимые знания в с++

p.s. Для ускорения вызова батников даже утилиту на делфи написал для вызова батников по горячим клавишам. И их принудильного перезапуска (перекомпиляция). ИМХО самое быстрое изученение... IDE много перепробовал - все тормозят сильно. Сборка пустышки под VC++ занимала минимум 20-30 секунд. Как и под DevCPP. Консоль (когда тормозит) за 7-8 секунд собирает, а если ускоряется около 3х секунд (почти догнал паскаль)...
Убежденный
Системный программист
 Аватар для Убежденный
14200 / 6215 / 986
Регистрация: 02.05.2013
Сообщений: 10,358
Завершенные тесты: 1
01.09.2014, 09:43     Преобразование String UTF8 в 1251 #10
Цитата Сообщение от Tester64 Посмотреть сообщение
Как перепрошить всю винду с анси на юникод не знаю, да и не хочу - другие программы "крокозябры" писать будут (включая RAR и 7ZIP).
Не нужно ничего "перепрошивать", Windows уже лет 15 юникодная изнутри.
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,841
Записей в блоге: 17
01.09.2014, 09:54     Преобразование String UTF8 в 1251 #11
Цитата Сообщение от DrOffset Посмотреть сообщение
Я тут сперва написал большой пост про пользу юникода и почему подстраиваться под устаревшую вин консоль (с дос кодировкой по умолчанию) не обязательно, но потом стер.
Ну и зачем стёр? Многим наверное было бы и полезно и интересно. Мне вот, например, интересно.
zer0mail
2187 / 1870 / 187
Регистрация: 03.07.2012
Сообщений: 6,651
Записей в блоге: 1
01.09.2014, 10:28     Преобразование String UTF8 в 1251 #12
Можно в вики почитать про юникод. Вообще, по нему полно ресурсов, например кратко и популярно: http://zelserg.livejournal.com/2570.html
Tester64
394 / 355 / 43
Регистрация: 22.05.2013
Сообщений: 2,461
01.09.2014, 18:06  [ТС]     Преобразование String UTF8 в 1251 #13
Цитата Сообщение от Убежденный Посмотреть сообщение
Windows уже лет 15 юникодная изнутри
Не знаю с какой стороны она изнутри юникоидная... Но консоль осталась в 1251. Вроде читал где-то что это можно поменять - то-ли подменой шрифтов, то-ли шаманством в реестре. Но все программы которые хотят вывести в консоль кирилицу используют 1251. Включая bat-файлы. Попробуйте в Win bat-файл в юникоде кирилицу вставить:
Bash
1
echo Привет
Не уверен что после хака консоли даже стандартные команды вроде dir кирилистические названия файлов правильно выводить будут (сейчас выводят)

А что такое юникод и чем он отличается от других кодировок, я думаю большинство и так знает. Но у него есть и свои минусы! По делфям помню (переводил проект с Delphi7 на Delphi2009) - каждый символ кодируется не одним байтом (как в других кодировках), от 2х до 4х!. Причем это плавающая величина и зависит от языка. И хранение в файлах и в памяти подобных строк увеличилось в 2-4 раза. Причем есть разные реализации юникода в разных ОС. Старые не поддерживали 4 а значит возможен глюк.

Добавлено через 11 минут
А вообще, инетересно, кто-нибудь (из Вас) еще кодит для консоли? Под Win или Linux? Слышал (активно не работал) что весь линукс работает в консоли и в основном написана на с/с++
DrOffset
6456 / 3830 / 885
Регистрация: 30.01.2014
Сообщений: 6,626
01.09.2014, 18:26     Преобразование String UTF8 в 1251 #14
Цитата Сообщение от Tester64 Посмотреть сообщение
Не знаю с какой стороны она изнутри юникоидная...
Windows юникодная изнутри. Консоль не юникодная по-умолчанию, и это сделано по всей видимости лишь для совместимости со старым ПО. Если мы пишем новое ПО нет никакой нужды подстраиваться под это. В VS например достаточно написать:
C++
1
_setmode(_fileno(stdout), _O_U16TEXT);
Чтобы перевести консоль в режим UTF16, соответственно, при наличии правильных шрифтов, wcout, wstring будут работать без каких-либо перекодировок.

Цитата Сообщение от Tester64 Посмотреть сообщение
Но консоль осталась в 1251
По-умолчанию она вообще в 866 кодировке (ДОС) в русской windows.

Цитата Сообщение от Tester64 Посмотреть сообщение
Слышал (активно не работал) что весь линукс работает в консоли и в основном написана на с/с++
Ну это не правда, что прям весь . Но консольные утилиты там гораздо лучше себя чувствуют, чем в windows, в том числе засчет развитой командной оболочки. Кстати в любом линуксе по-умолчанию используется кодировка юникода UTF-8.
_Ivana
2186 / 1391 / 124
Регистрация: 01.03.2013
Сообщений: 4,143
Записей в блоге: 2
01.09.2014, 23:23     Преобразование String UTF8 в 1251 #15
Цитата Сообщение от gru74ik Посмотреть сообщение
Ну и зачем стёр? Многим наверное было бы и полезно и интересно. Мне вот, например, интересно.
+1. Мне тоже всегда интересно почитать имхи специалистов, тем более, если им можно потом еще задать вопрос. А вики мы в любом случае почитать можем.
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,841
Записей в блоге: 17
02.09.2014, 06:46     Преобразование String UTF8 в 1251 #16
Цитата Сообщение от Tester64 Посмотреть сообщение
Слышал (активно не работал) что весь линукс работает в консоли
Там всё вполне себе цивилизованно - окошечки, менюшечки. Попробуй ради интереса Ubuntu поставить, к примеру. Посмотришь сам.
Tester64
394 / 355 / 43
Регистрация: 22.05.2013
Сообщений: 2,461
02.09.2014, 17:36  [ТС]     Преобразование String UTF8 в 1251 #17
Цитата Сообщение от gru74ik Посмотреть сообщение
Там всё вполне себе цивилизованно - окошечки, менюшечки. Попробуй ради интереса Ubuntu поставить, к примеру. Посмотришь сам
"По приколу" делать это не хочется, а для работы не нужно (на 80% привязан к винде - остальное веб). Конечно раньше ставил (в виртуальные машины), даже где-то в коллекции лежит... Конечно там можно включить графику и работать только в ней. Но меня инетересует не это! Насколько сейчас активно кодят под консоль в С++? Нужна ли эта технология еще? Или давно замещена графикой? Конечно понимаю, что все сетевые технологии консольные, но кроме сетей?
DrOffset
6456 / 3830 / 885
Регистрация: 30.01.2014
Сообщений: 6,626
02.09.2014, 18:17     Преобразование String UTF8 в 1251 #18
Цитата Сообщение от Tester64 Посмотреть сообщение
Насколько сейчас активно кодят под консоль в С++?
Нет такого понятия "кодить под консоль".
Есть прикладное ПО, которое может быть с графическим или текстовым интерфейсом. Пользовательский интерфейс - это только малая часть процесса разработки ПО, поэтому вакансии "кодить под консоль" и не найдешь. Потому что обычно "кодят", чтобы решить некую задачу, а текстовый у этой программы будет интерфейс или графический - это не столь важно, это системные архитекторы и дизайнеры пусть решают.
Причем, помимо прикладного ПО есть еще куча разного системного и околосистемного софта: сервисы, библиотеки, драйвера, embedded ПО, ядра ОС, физические движки игр и т.д. и т.п., для которых вообще не применимо понятие пользовательский интерфейс (или этот интерфейс штука специфическая, например две кнопки на устройстве вкл. и выкл.). Эта категория тоже занимает довольно ощутимую долю рынка. Мы ее не рассматриваем что ли?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.09.2014, 20:58     Преобразование String UTF8 в 1251
Еще ссылки по теме:

C++ преобразование string в char*
C++ Преобразование String в Byte C++
{SetConsoleCP(1251); SetConsoleOutputCP(1251); сломал русс шрифт C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
NeoMatrix
Модератор
 Аватар для NeoMatrix
3000 / 586 / 55
Регистрация: 24.05.2011
Сообщений: 7,779
Записей в блоге: 1
02.09.2014, 20:58     Преобразование String UTF8 в 1251 #19
Цитата Сообщение от Tester64 Посмотреть сообщение
весь линукс работает в консоли
Я вас умоляю! Для повышения вашего уровня эрудиции в этом вопросе крайне рекомендую зайти хотя бы в Windows vs Linux (0Dh) или У кого как выглядит рабочий стол? (2), где вполне достаточно скринов рабстолов линукс
Yandex
Объявления
02.09.2014, 20:58     Преобразование String UTF8 в 1251
Ответ Создать тему
Опции темы

Текущее время: 14:23. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru