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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.88
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
#1

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

31.08.2014, 19:10. Просмотров 2889. Ответов 18
Метки нет (Все метки)

Нашел пример:

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)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.08.2014, 19:10
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Преобразование String UTF8 в 1251 (C++):

{SetConsoleCP(1251); SetConsoleOutputCP(1251); сломал русс шрифт - C++
получилось так что скомпилил и запустил программу со строкой {SetConsoleCP(1251); SetConsoleOutputCP(1251); теперь...

запрошено преобразование от ‘const std::string*’ к нескалярному типу ‘std::string’ - C++
private: std::string firstName; }; std::string ClientData::getFirstName() const{ return firstName; } Дает в итоге...

Преобразование string* в string - C++
Здравствуйте, друзья. У меня есть класс. В нем описано поле string *GPS; В конструкторе выделяю память. Передаю именно *_GPS для...

Преобразование Double в string - C++
Допустим у меня есть число double n = 0.0000000000 мне нужно преобразовать его в строку string s = 0.0000000000. Как это сделать?

Преобразование string в int - C++
Всем привет, нужно преобразовать string в int #include <iostream> #include <stdlib.h> #include <string.h> #include <stdio.h>...

Преобразование string в int - C++
Добрый день. Есть переменная типа string, в которой записана цифра. Как мою строку перевести к int?

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Ryzhikov_A
6 / 6 / 0
Регистрация: 14.10.2012
Сообщений: 36
31.08.2014, 20:09 #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
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
31.08.2014, 21:04  [ТС] #3
Вторая часть кода подошла, но не первая. Она работает, но мне нужно другое:
std::string (или std::wstring) в wchar_t
Ryzhikov_A
6 / 6 / 0
Регистрация: 14.10.2012
Сообщений: 36
31.08.2014, 21:22 #4
Аналогично
C++
1
2
std::wstring line(L"test string");
const wchar_t* szName = line.c_str();
DrOffset
7089 / 4230 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
31.08.2014, 21:49 #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
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
31.08.2014, 22:25  [ТС] #6
ИДЕАЛЬНО!
Правда прилось еще добавить
C++ (Qt)
1
#include <vector>
(я как новичок этого не знал)
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
01.09.2014, 01:47 #7
Хм, все бегут без оглядки от CP1251 и от всяких понаехавших "кодовых страниц", а тут наоборот, UTF-8 не нравится
DrOffset
7089 / 4230 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
01.09.2014, 01:50 #8
Цитата Сообщение от gromo Посмотреть сообщение
Хм, все бегут без оглядки от CP1251, а тут наоборот, UTF-8 не нравится
Пусть сам налетает на все грабли
Всех все равно не переубедишь. Я тут сперва написал большой пост про пользу юникода и почему подстраиваться под устаревшую вин консоль (с дос кодировкой по умолчанию) не обязательно, но потом стер.
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
01.09.2014, 03:48  [ТС] #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х секунд (почти догнал паскаль)...
Убежденный
Системный программист
Эксперт С++
15506 / 7004 / 1106
Регистрация: 02.05.2013
Сообщений: 11,440
Завершенные тесты: 1
01.09.2014, 09:43 #10
Цитата Сообщение от Tester64 Посмотреть сообщение
Как перепрошить всю винду с анси на юникод не знаю, да и не хочу - другие программы "крокозябры" писать будут (включая RAR и 7ZIP).
Не нужно ничего "перепрошивать", Windows уже лет 15 юникодная изнутри.
gru74ik
Модератор
Эксперт CЭксперт С++
4150 / 1776 / 197
Регистрация: 20.02.2013
Сообщений: 4,898
Записей в блоге: 21
01.09.2014, 09:54 #11
Цитата Сообщение от DrOffset Посмотреть сообщение
Я тут сперва написал большой пост про пользу юникода и почему подстраиваться под устаревшую вин консоль (с дос кодировкой по умолчанию) не обязательно, но потом стер.
Ну и зачем стёр? Многим наверное было бы и полезно и интересно. Мне вот, например, интересно.
zer0mail
2332 / 1958 / 192
Регистрация: 03.07.2012
Сообщений: 7,021
Записей в блоге: 1
01.09.2014, 10:28 #12
Можно в вики почитать про юникод. Вообще, по нему полно ресурсов, например кратко и популярно: http://zelserg.livejournal.com/2570.html
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
01.09.2014, 18:06  [ТС] #13
Цитата Сообщение от Убежденный Посмотреть сообщение
Windows уже лет 15 юникодная изнутри
Не знаю с какой стороны она изнутри юникоидная... Но консоль осталась в 1251. Вроде читал где-то что это можно поменять - то-ли подменой шрифтов, то-ли шаманством в реестре. Но все программы которые хотят вывести в консоль кирилицу используют 1251. Включая bat-файлы. Попробуйте в Win bat-файл в юникоде кирилицу вставить:
Bash
1
echo Привет
Не уверен что после хака консоли даже стандартные команды вроде dir кирилистические названия файлов правильно выводить будут (сейчас выводят)

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

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

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

Цитата Сообщение от Tester64 Посмотреть сообщение
Слышал (активно не работал) что весь линукс работает в консоли и в основном написана на с/с++
Ну это не правда, что прям весь . Но консольные утилиты там гораздо лучше себя чувствуют, чем в windows, в том числе засчет развитой командной оболочки. Кстати в любом линуксе по-умолчанию используется кодировка юникода UTF-8.
_Ivana
3053 / 1740 / 150
Регистрация: 01.03.2013
Сообщений: 4,925
Записей в блоге: 2
01.09.2014, 23:23 #15
Цитата Сообщение от gru74ik Посмотреть сообщение
Ну и зачем стёр? Многим наверное было бы и полезно и интересно. Мне вот, например, интересно.
+1. Мне тоже всегда интересно почитать имхи специалистов, тем более, если им можно потом еще задать вопрос. А вики мы в любом случае почитать можем.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.09.2014, 23:23
Привет! Вот еще темы с ответами:

Преобразование string в int - C++
Помогите пожалуйста с преобразованием string к типу int, быть может не напрямую но хоть как нибудь, очень надо!!!

Преобразование string to char - C++
В общем никак не получается перегнать из строки в чар. Что надо: Имеется StringGrid и структура. Обьявлена структура как: struct...

Преобразование int в string - C++
не могу не как реализовать преобразование int в string, подскажите как это сделать ? например число int q=123, мне надо его сделать так что...

Преобразование из string в double - C++
Объясните пожалуйста в чем связь между преобразованием данный из string в double и библиотекой русского языка Вот так работает #include...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
01.09.2014, 23:23
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru