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

Перевод кодировки - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 58, средняя оценка - 4.76
Lindemann66
 Аватар для Lindemann66
3 / 3 / 0
Регистрация: 28.04.2010
Сообщений: 162
01.08.2011, 16:43     Перевод кодировки #1
Всем привет!

Такая задача
Имеем html-код
Знаем кодировку (charset)
Если кодировка, отличная от UTF-8 - нужно выполнить преобразование к UTF-8

Какими способами (желательно, без использования сторонних библиотек и функционала, таких как boost, QT и т.д.) привести текст к нужной кодировке?

Есть ссылка на хабрахабр с описанием - Кодировки в C++ - к сожалению, не подходит, потому что там используется boost.

Буду признателен за любые ответы
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.08.2011, 16:43     Перевод кодировки
Посмотрите здесь:

C++ Нет кодировки?!
C++ Кодировки в С++
C++ Кодировки
C++ Перевод из кодировки UTF - 8 в ANSI
C++ Ошибка кодировки?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
soft.creator
 Аватар для soft.creator
103 / 103 / 4
Регистрация: 17.10.2010
Сообщений: 283
01.08.2011, 19:03     Перевод кодировки #2
C++
1
2
MultiByteToWideString(1251, ...);
WideStringToMultiByte(CP_UTF8, ...);
Lindemann66
 Аватар для Lindemann66
3 / 3 / 0
Регистрация: 28.04.2010
Сообщений: 162
02.08.2011, 11:47  [ТС]     Перевод кодировки #3
Спасибо!
А можешь объяснить, как это работает?

Вот функция MultiByteToWideString - это функция преобразования какой-либо кодировки в т.н "широкую" кодировку, т.е. в UTF
а функция WideStringToMultiByte - наоборот, из UTF в другую?

И какой заголовочный файл нужно подключать, чтобы использовать данные функции?
Я пишу на MFC

Добавлено через 2 минуты
На одном "форуме" нашёл совет

#include "atlconv.h"
...
char* pstrString = "Hello There!";
wchar_t* pUnicodeString = 0;

USES_CONVERSION;

// Convert Ansi to Unicode.
pUnicodeString = A2W( pstrString);
// Convert Unicode to Ansi.
pstrString = W2A( pUnicodeString);
Но тут выполняются преобразования UTF <-> ANSI
А если не ANSI?

Добавлено через 3 минуты
А ещё есть некая функция loadU..
C++
1
2
3
4
5
    
std::wstring widestr = std::wstring(str.begin(), str.end());
wchar_t* widecstr = widestr.c_str();
CA2W pszWide(widecstr);
loadU(pszWide);
soft.creator
 Аватар для soft.creator
103 / 103 / 4
Регистрация: 17.10.2010
Сообщений: 283
02.08.2011, 11:49     Перевод кодировки #4
MultiByteToWideString преобразует строку из указанной кодировки (например, 1251) в Unicode.
WideStringToMultiByte преобразует из Юникода в любую другую, указываем UTF8.
Вот и вся магия. Обе функции описаны в MSDN. Работа за пару минут делается.

Заголовочник windows.h.

Все остальные функции/макросы - от лукавого, все равно внутри вызывают именно эти две.
Lindemann66
 Аватар для Lindemann66
3 / 3 / 0
Регистрация: 28.04.2010
Сообщений: 162
02.08.2011, 11:59  [ТС]     Перевод кодировки #5
Большое спасибо!

Цитата Сообщение от soft.creator Посмотреть сообщение
Заголовочник windows.h.
Но этот заголовочник не даёт доступ к MultiByteToWideString
soft.creator
 Аватар для soft.creator
103 / 103 / 4
Регистрация: 17.10.2010
Сообщений: 283
02.08.2011, 12:45     Перевод кодировки #6
Прошу прощения, WideCharToMultiByte и MultiByteToWideChar функции называются
Lindemann66
 Аватар для Lindemann66
3 / 3 / 0
Регистрация: 28.04.2010
Сообщений: 162
02.08.2011, 15:45  [ТС]     Перевод кодировки #7
Кстати!
А в чём разница MultiByteToWideString и MultiByteToWideChar?
В MSDN описана именно вторая функция, и, как я понял, именно её следует использовать
Например, как здесь

Добавлено через 54 секунды
Цитата Сообщение от soft.creator Посмотреть сообщение
Прошу прощения, WideCharToMultiByte и MultiByteToWideChar функции называются
как раз догадался

Добавлено через 18 минут
Кстати, заголовочником для этих функций также может быть winnls.h


Добавлено через 2 часа 36 минут
Да, кстати, вопрос

Не важно, какого типа должна быть строка?
CString, LPWSTR, LPSTR, какая-либо ещё?

Просто я делаю так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//перекодировка строки к кодировке UTF-8
CString ContvertToUTF8(CString str, CString from) {
    map<CString, int> codePages;
    codePages["utf-16"] = 1200;
    codePages["windows-1250"] = 1250;
    codePages["windows-1251"] = 1251;
    codePages["koi8-r"] = 20866;
    codePages["koi8-u"] = 21866;
    codePages["koi8-u"] = 21866;
 
    //если данной кодировки в списке нет
    if (codePages.find(from) == codePages.end()) {
        AfxMessageBox("Неизвестная кодировка " + from);
        return "";
    }   
 
    //Get the size of the string by setting the 4th parameter to -1:
    DWORD dwNum = MultiByteToWideChar(codePages[from], 0, str, -1, NULL, 0);
 
    //Allocate space for wide char string:
    wchar_t *pwText;
    pwText = new wchar_t[dwNum];
    if(!pwText) {
        delete []pwText;
    }
    //Then convert:
    int res = MultiByteToWideChar(codePages[from], 0, str, -1, pwText, dwNum);
 
    return CString(pwText);
}
Просто, когда я смотрю в результат кодировки, там точно такой же текст без всяких изменений
И в БД, после добавления, символы тоже не меняются
Может, я в чём-то ошибся?
soft.creator
 Аватар для soft.creator
103 / 103 / 4
Регистрация: 17.10.2010
Сообщений: 283
02.08.2011, 15:55     Перевод кодировки #8
Неправильно. Где вызов WideCharToMultiByte?
И перед выходом из функции неплохо бы удалить pwText
C++
1
2
3
        if(!pwText) {
                delete []pwText;
        }
Сломал мозг...
Lindemann66
 Аватар для Lindemann66
3 / 3 / 0
Регистрация: 28.04.2010
Сообщений: 162
02.08.2011, 16:18  [ТС]     Перевод кодировки #9
Цитата Сообщение от soft.creator Посмотреть сообщение
Неправильно. Где вызов WideCharToMultiByte?
Сломал мозг...
Дада, уже понял
спасибо

Добавлено через 4 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//перекодировка строки к кодировке UTF-8
CString ContvertToUTF8(CString str, CString from) {
    map<CString, int> codePages;
    codePages["utf-16"] = 1200;
    codePages["windows-1250"] = 1250;
    codePages["windows-1251"] = 1251;
    codePages["koi8-r"] = 20866;
    codePages["koi8-u"] = 21866;
    codePages["koi8-u"] = 21866;
 
    //если данной кодировки в списке нет
    if (codePages.find(from) == codePages.end()) {
        AfxMessageBox("Неизвестная кодировка " + from);
        return "";
    }   
 
    //Конвертируем исходный текст в WideString
    //1 - исходная кодировка
    //2 - 0 - доп. флаги не установлены
    //3 - строка для конвертации
    //4 - -1 - исходная строка заканчивается \0
    //5, 6 - необязательные
    DWORD dwNum = MultiByteToWideChar(codePages[from], 0, str, -1, NULL, 0);
    //выделяем память под wide char строку:
    wchar_t *pwText;
    pwText = new wchar_t[dwNum];
    if(!pwText) {
        delete []pwText;
    }
    MultiByteToWideChar(codePages[from], 0, str, -1, pwText, dwNum);
 
    //Конвертируем WideString в UTF-8
    dwNum = WideCharToMultiByte(CP_UTF8, 0, pwText, -1, NULL, 0, NULL, NULL);
    char *Text;
    Text = new char[dwNum];
    if(!Text) {
        delete []Text;
    }
    WideCharToMultiByte(CP_UTF8, 0, pwText, -1, Text, 0, NULL, NULL);
 
    CString res = CString(Text);
 
    //очищаем выделенную под переменные память
    delete []pwText;
    delete []Text;
 
    return res;
}
Вот, теперь вот так
Правда, после выполнения данных операций в res появляются только буквы Н и в конце ещё что-то, явно не то..

Добавлено через 3 минуты
Всё, исправился
C++
1
WideCharToMultiByte(CP_UTF8, 0, pwText, -1, Text, dwNum, NULL, NULL);
dwNum забыл

Добавлено через 4 минуты
Всё, работает спасибо всем за овтеты
Dimrad
Сообщений: n/a
09.03.2013, 21:27     Перевод кодировки #10
// ANSI -> UTF8
// чтобы получилось нужно ANSI -> UTF16 -> UTF8
// с помощью макросов ATL

CStringA sAnsi = "ВОВА";
CStringW sUtf16 = CA2W(sAnsi, CP_ACP);
CStringA sUtf8 = CW2A(sUtf16, CP_UTF8);

// И обратно UTF8 -> ANSI
//
CStringA sAnsi, sUtf8;
sUtf8 = "Сканворд";
sAnsi= CA2W(sUtf8, CP_UTF8);
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.10.2014, 17:02     Перевод кодировки
Еще ссылки по теме:

C++ Кодировки, языки
C++ Преобразование кодировки
Кодировки (ошибки кодировки) в логировании C++

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

Или воспользуйтесь поиском по форуму:
Retyrn0
45 / 45 / 3
Регистрация: 24.06.2013
Сообщений: 675
Завершенные тесты: 1
29.10.2014, 17:02     Перевод кодировки #11
C++
1
2
3
4
5
6
7
void gets_utf8(char*buf)
{
    wchar_t tbuf[buf_len];
    gets(buf);
    MultiByteToWideChar(1251,0,buf,-1,tbuf,buf_len);
    WideCharToMultiByte(CP_UTF8,0,tbuf,-1,buf,buf_len,NULL,NULL);
}
Вот что надо было)
Yandex
Объявления
29.10.2014, 17:02     Перевод кодировки
Ответ Создать тему
Опции темы

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