Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: (faq)Как перевести строку из UTF-8 в ANSI?  (Прочитано 36729 раз)
0 Пользователей и 1 Гость смотрят эту тему.
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« : 14-05-2005 15:39 » 

Есть строка символов (страничка из Инета) в кодировке utf-8 (строка char*).
Как мне ее получить в формате CString или в char* в кодировке ANSI (cp 1251) ?
Приведите пример, пожалуйста...
MSVC6
« Последнее редактирование: 01-05-2007 07:30 от Алексей1153++ » Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 14-05-2005 15:53 » 

При помощи MultiByteToWideChar можно перевести из utf8 в Unicode без потери информации.  Из Unicode можно будет сконвертировать в CP1251 при помощи WideCharToMultiByte, но возможны потери, так как Unicode значительно шире, чем однобайтовые кодовые страницы.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 16-05-2005 10:22 » new

Пример: перевести строку из UTF8 в Unicode, затем из Unicode в 1251

если опустить проверки ошибок, то использование такое:
Код:
char * cp1251_string = unicode_to_1251(utf8_to_unicode(utf8_string));

Как реализовать unicode_to_1251 и utf8_to_unicode см. пример.

Код:
#include <windows.h>
#include <stdio.h>

wchar_t * utf8_to_unicode(char *utf8_string)
{
int err;
wchar_t * res;
int res_len = MultiByteToWideChar(
CP_UTF8, // Code page
0, // No flags
utf8_string, // Multibyte characters string
-1, // The string is NULL terminated
NULL, // No buffer yet, allocate it later
0 // No buffer
);
if (res_len == 0)
{
printf("Failed to obtain utf8 string length\n");
return NULL;
}
res = calloc(sizeof(wchar_t), res_len);
if (res == NULL)
{
printf("Failed to allocate unicode string\n");
return NULL;
}
err = MultiByteToWideChar(
CP_UTF8, // Code page
0, // No flags
utf8_string, // Multibyte characters string
-1, // The string is NULL terminated
res, // Output buffer
res_len // buffer size
);
if (err == 0)
{
printf("Failed to convert to unicode\n");
free(res);
return NULL;
}
return res;
}

char * unicode_to_1251(wchar_t *unicode_string)
{
int err;
char * res;
int res_len = WideCharToMultiByte(
1251, // Code page
0, // Default replacement of illegal chars
unicode_string, // Multibyte characters string
-1, // Number of unicode chars is not known
NULL, // No buffer yet, allocate it later
0, // No buffer
NULL, // Use system default
NULL // We are not interested whether the default char was used
);
if (res_len == 0)
{
printf("Failed to obtain required cp1251 string length\n");
return NULL;
}
res = calloc(sizeof(char), res_len);
if (res == NULL)
{
printf("Failed to allocate cp1251 string\n");
return NULL;
}
err = WideCharToMultiByte(
1251, // Code page
0, // Default replacement of illegal chars
unicode_string, // Multibyte characters string
-1, // Number of unicode chars is not known
res, // Output buffer
res_len, // buffer size
NULL, // Use system default
NULL // We are not interested whether the default char was used
);
if (err == 0)
{
printf("Failed to convert from unicode\n");
free(res);
return NULL;
}
return res;
}

int main(int argc, char ** argv)
{
char utf8_string[] = "UTF-8 + русский текст";
wchar_t * unicode_string;
char * cp1251_string;

unicode_string = utf8_to_unicode(utf8_string);
if (unicode_string == NULL)
{
printf("Failed to convert!\n" );
return 1;
}
MessageBoxW(NULL, unicode_string, L"Unicode", 0);
cp1251_string = unicode_to_1251(unicode_string);
free(unicode_string);
if (cp1251_string == NULL)
{
printf("Failed to convert from unicode!\n");
return 2;
}
MessageBoxA(NULL, cp1251_string, "CP1251", 0);
return 0;
}
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 23-05-2005 08:30 » 

utf8 -- многобайтовая кодировка.  Одним байтом представляются символы из US-ASCII (из первой половины таблицы, до 128). Все остальные символы из не-ASCII части Unicode представляются последовательностью байт длиной от 2-х до 4-х.  Поэтому если в тексте много букв, не принадлежащих английскому алфавиту, то размер текста будет больше, чем при однобайтовой кодировке.

Подробнее см. rfc3629, ftp://ftp.rfc-editor.org/in-notes/rfc3629.txt и стандарт Unicode http://www.unicode.org/versions/Unicode4.0.0/
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
dimka20
Гость
« Ответ #4 : 21-02-2009 20:09 » 

вроде работает способ попросче:
Код:
for (i = 0, k = 0; s[i]; k ++)
{
if (s[i] < 0)
{
s[k] = (s[i] + 48) * 64 + s[i + 1] + 48;
i += 2;
}
else
{
s[k] = s[i];
i ++;
}
}
s[k] = NULL;
оно переведёт нечто вроде этого: "СЏ забыл взять сдачу"
в нечто вроде этого: "я забыл взять сдачу"
=)
« Последнее редактирование: 21-02-2009 20:15 от Finch » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #5 : 21-02-2009 20:19 » 

Это может быть корректно для русского языка. А если тебе встретится другая кодировка, то ты получиш небольшой такой нежданчик. И кстати я бы проверял 8 бит, а не то, что число отрицательное. Некоторые компиляторы char считают как безнаковое число.
« Последнее редактирование: 21-02-2009 20:21 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
dimka20
Гость
« Ответ #6 : 21-02-2009 20:25 » 

оу, спасибо большое что исправили пост )) а то я сижу ищу ссылку edit )

ну вообще да, для другого языка нужно будет подбирать другие цифры. а в самом простом случае и для русских - норм ))
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 22-02-2009 08:51 » 

dimka20, не стоит упрощать в ущерб совместимости - потом боком выйдет.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines