MultiByteToWideString(1251, ...);
WideStringToMultiByte(CP_UTF8, ...);
Перевод кодировки
Такая задача
Имеем html-код
Знаем кодировку (charset)
Если кодировка, отличная от UTF-8 - нужно выполнить преобразование к UTF-8
Какими способами (желательно, без использования сторонних библиотек и функционала, таких как boost, QT и т.д.) привести текст к нужной кодировке?
Есть ссылка на хабрахабр с описанием - Кодировки в C++ - к сожалению, не подходит, потому что там используется boost.
Буду признателен за любые ответы :)
Цитата: Lindemann66
Всем привет!
Какими способами (желательно, без использования сторонних библиотек и функционала, таких как boost, QT и т.д.) привести текст к нужной кодировке?
Какими способами (желательно, без использования сторонних библиотек и функционала, таких как boost, QT и т.д.) привести текст к нужной кодировке?
Очевидно, написать собственный перекодировщик. Есть еще варианты, с учетом процитированного? :)
Цитата: Lindemann66
Всем привет!
Такая задача
Имеем html-код
Знаем кодировку (charset)
Если кодировка, отличная от UTF-8 - нужно выполнить преобразование к UTF-8
Какими способами (желательно, без использования сторонних библиотек и функционала, таких как boost, QT и т.д.) привести текст к нужной кодировке?
Есть ссылка на хабрахабр с описанием - Кодировки в C++ - к сожалению, не подходит, потому что там используется boost.
Буду признателен за любые ответы :)
Такая задача
Имеем html-код
Знаем кодировку (charset)
Если кодировка, отличная от UTF-8 - нужно выполнить преобразование к UTF-8
Какими способами (желательно, без использования сторонних библиотек и функционала, таких как boost, QT и т.д.) привести текст к нужной кодировке?
Есть ссылка на хабрахабр с описанием - Кодировки в C++ - к сожалению, не подходит, потому что там используется boost.
Буду признателен за любые ответы :)
libiconv: http://www.gnu.org/s/libiconv/
Порт под виндовс: http://gnuwin32.sourceforge.net/packages/libiconv.htm
Вот по этой ссылке http://www.gnu.org/software/libiconv/
Осталось только определиться с тем, каковы условия её использования
Дело то в том, что, допустим, QT очень дорога для коммерческого использования, а boost слишком громоздок, и использовать его для одной лишь кодировки глупо
Вот почему я написал про
Цитата: Lindemann66
желательно, без использования сторонних библиотек и функционала, таких как boost, QT и т.д.
Ты вот, случайно, не знаешь про libiconv?
Цитата: mike
libiconv: http://www.gnu.org/s/libiconv/
Порт под виндовс: http://gnuwin32.sourceforge.net/packages/libiconv.htm
Порт под виндовс: http://gnuwin32.sourceforge.net/packages/libiconv.htm
только сейчас о ней подумал :)
Под Виндой ищем номер кодовой страницы в HKEY_CLASSES_ROOT\MIME\Database\Charset, потом вызываем сначала MultiByteToWideChar с найденным кодом, а потом WideCharToMultiByte с CP_UTF8.
Ramon, ого! Когда надо было, искал, как можно сделать официальным способом, но не нашёл. Возможно, плохо искал. Да и вряд ли оно в Delphi есть искаропки. Теперь буду знать, спасибо.
Предложили использовать
Код:
но тут встаёт вопрос
функция MultiByteToWideString - это функция преобразования какой-либо кодировки в т.н "широкую" кодировку, т.е. в UTF
а функция WideStringToMultiByte - наоборот, из UTF в другую?
И какой заголовочный файл нужно подключать, чтобы использовать данные функции, учитывая, что я пишу на MFC
А ещё на одном форуме нашёл совет
Цитата:
#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);
...
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?
А ещё есть некая функция loadU..
Код:
std::wstring widestr = std::wstring(str.begin(), str.end());
wchar_t* widecstr = widestr.c_str();
CA2W pszWide(widecstr);
loadU(pszWide);
wchar_t* widecstr = widestr.c_str();
CA2W pszWide(widecstr);
loadU(pszWide);
libiconv и MLang - это, конечно, хорошо, но мне почему-то больше хочется опираться на стандартный функционал...
Не важно, какого типа должна быть строка?
CString, LPWSTR, LPSTR, какая-либо ещё?
Просто я делаю так:
Код:
//перекодировка строки к кодировке 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);
}
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);
}
Просто, когда я смотрю в результат кодировки, там точно такой же текст без всяких изменений
И в БД, после добавления, символы тоже не меняются
Может, я в чём-то ошибся?
Ясно ведь было сказано до этого, что одним преобразованием не обойтись. Вначале MultiByteToWideChar превращает исходную кодировку (1251) в wchar_t, а потом вызовом WideCharToMultiByte wchar_t превращается в CP_UTF8.
Цитата: Freeman
Ясно ведь было сказано до этого, что одним преобразованием не обойтись. Вначале MultiByteToWideChar превращает исходную кодировку (1251) в wchar_t, а потом вызовом WideCharToMultiByte wchar_t превращается в CP_UTF8.
да, я ещё вчера это исправил, спасибо :)
вот код, если кому интересно
он рабочий
Код:
// обработчики сообщений CInternetPoll4View
//перекодировка строки к кодировке 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
DWORD dwNum = MultiByteToWideChar(codePages[from], 0, str, -1, NULL, 0);
//выделяем память под wide char строку:
wchar_t *pwText;
pwText = new wchar_t[dwNum];
if(!pwText) {
return "";
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) {
return "";
delete []Text;
}
WideCharToMultiByte(CP_UTF8, 0, pwText, -1, Text, dwNum, NULL, NULL);
CString res = CString(Text);
//очищаем выделенную под переменные память
delete []pwText;
delete []Text;
return res;
}
//перекодировка строки к кодировке 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
DWORD dwNum = MultiByteToWideChar(codePages[from], 0, str, -1, NULL, 0);
//выделяем память под wide char строку:
wchar_t *pwText;
pwText = new wchar_t[dwNum];
if(!pwText) {
return "";
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) {
return "";
delete []Text;
}
WideCharToMultiByte(CP_UTF8, 0, pwText, -1, Text, dwNum, NULL, NULL);
CString res = CString(Text);
//очищаем выделенную под переменные память
delete []pwText;
delete []Text;
return res;
}