Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 32, средняя оценка - 4.78
Nikfel
56 / 28 / 14
Регистрация: 30.05.2009
Сообщений: 158
#1

Как конвертировать Unicode в Ansi? - C++

02.01.2013, 15:49. Просмотров 5667. Ответов 11
Метки нет (Все метки)

Я написал свою функцию конвертирования из Unicode в Ansi, но она не правильно кодирует символы русского языка.
Как такое исправить?

C++
1
2
3
4
5
6
7
8
9
10
void WideToChar(wchar_t *strS, char *strText)
{
    wchar_t *p = strS;
    char *p1 = strText;
    while (*p) {
        *p1 = (char) *p;
        p1++;
        p++;
    }
}
Проверка переполнения буфера отсутствует, так что аккуратнее с этой функцией.
Меня интересует почему так происходит при русских символах или это из-за того что символы юникода занимают 2 байта?
Заранее спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.01.2013, 15:49
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Как конвертировать Unicode в Ansi? (C++):

Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк?
Всем доброго дня) Подскажите такую весчь: можно ли в консольном приложении...

Как конвертировать строку из Unicode GB2312
Знаний как таковых в С++ нет, а хочется на ардуине проект запустить. К...

ANSI to Unicode
Hi all. Вопрос к экспертам :) Хочу сохранить строку текста (кириллица) в...

ANSI to Unicode
Всем доброго времени суток! Есть задачка преобразовать строку в cp1251 в...

ANSI и UNICODE
#include <iostream> #include <windows.h> using namespace std; int...

Перевод из Unicode в ANSI
Привет! При переводе из Unicode в ANSI юзаю вот эти две функции: CharToOemW и...

11
Герц
524 / 341 / 12
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
02.01.2013, 16:17 #2
Ты тупо копируешь поэлементно строку двухбайтовых символов в строку однобайтовых, выполняя понижающее приведение. Значения теряются.
0
Nikfel
56 / 28 / 14
Регистрация: 30.05.2009
Сообщений: 158
02.01.2013, 17:43  [ТС] #3
А как разложить строку на все байты, чтобы обрабатывать каждый байт, исключая байт 00?
0
xtorne21st
интересующийся
304 / 275 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
02.01.2013, 21:53 #4
попробуй вместо char использовать int; в случаи успеха и обращения у тебя будет автоматическое приведение типов.

Добавлено через 30 минут
А вообще в <stdlib.h> объявлена функция mbstowcs(). Вот её прототип:
C++
1
size_t mbstowcs(wchar_t *dest, const char *src, size_t n);
Из описания Шилдт спавочник С:
Функция mbstowcs() преобразует многобайтовую строку, адресуемую параметром in, в строку, состоящую из двухбайтовых символов, и помещает результат в массив, адресуемый параметром out. В массиве out будет сохранено в памяти только size байтов.
В версии С99 к параметрам out и in применен квалификатор restrict.
Функция mbstowcs() возвращает количество преобразованных многобайтовых символов. При возникновении ошибки функция возвращает значение -1.


Добавлено через 7 минут
ПС. Информация не актуальна, так как приводиться преобразование в wchar_t, а не наоборот
0
ValeryS
Модератор
7129 / 5397 / 669
Регистрация: 14.02.2011
Сообщений: 18,216
02.01.2013, 22:03 #5
Цитата Сообщение от xtorne21st Посмотреть сообщение
попробуй вместо char использовать int;
вообще то int 4 байта
лучше short int
Nikfel,
ты в наглую теряешь первый байт(нулевой) в каждом wchar_t, а там код страны
да и русских кодировок до проха ты в какую конвертить хочешь?
первые два байта показывают тип кодировки
почитай
http://ru.wikipedia.org/wiki/Юникод
сколько разновидностей юникодов
1
xtorne21st
интересующийся
304 / 275 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
02.01.2013, 22:11 #6
Цитата Сообщение от ValeryS Посмотреть сообщение
вообще то int 4 байта
лучше short int
У меня int и short занимают одинаково 4 байта.
0
Avazart
Эксперт С++
7676 / 5585 / 542
Регистрация: 10.12.2010
Сообщений: 25,060
Записей в блоге: 17
02.01.2013, 22:13 #7
Цитата Сообщение от Nikfel Посмотреть сообщение
конвертирования из Unicode в Ansi
Есть разный Unicode и разный Ansi
0
ValeryS
Модератор
7129 / 5397 / 669
Регистрация: 14.02.2011
Сообщений: 18,216
02.01.2013, 22:35 #8
Цитата Сообщение от xtorne21st Посмотреть сообщение
меня int и short занимают одинаково 4 байта.
вполне возможно ( не противоречит стандарту) я говорил про Win32
Таблица юникоде кодов
http://unicode-table.com/ru/
0
Nikfel
56 / 28 / 14
Регистрация: 30.05.2009
Сообщений: 158
03.01.2013, 12:38  [ТС] #9
Переписал таким образом, вроде работает. Интересно только в каком случае может не сработать?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void WideToChar(wchar_t *strS, char *strText)
{
    const wchar_t minRus = 0x0410;//первый русский символ Unicode
    const wchar_t maxRus = 0x044f;//последний русский символ Unicode
    const char minR = 192;//первый русский символ Ansi
    int i = 0;
    wchar_t *p = strS;
    char *p1 = strText;
    while (*p) {
        if (*p >= minRus && *p <= maxRus) {i = *p - minRus; *p1 = minR + i;} else *p1 = (char) *p;
        p1++;
        p++;
    }
}
0
ValeryS
Модератор
7129 / 5397 / 669
Регистрация: 14.02.2011
Сообщений: 18,216
03.01.2013, 12:42 #10
Цитата Сообщение от Nikfel Посмотреть сообщение
Интересно только в каком случае может не сработать?
в случае букв Ё =0х0401 и ё =0х451
1
Nikfel
56 / 28 / 14
Регистрация: 30.05.2009
Сообщений: 158
03.01.2013, 13:30  [ТС] #11
Остановился на таком варианте:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void WideToChar(wchar_t *strS, char *strText)
{
    const wchar_t minRus = 0x0410;
    const wchar_t maxRus = 0x044f;
    const wchar_t eRus = 0x0401;
    const wchar_t e1Rus = 0x0451;
    const char e1 = 168;
    const char e2 = 184;
    const char minR = 192;
    int i = 0;
    wchar_t *p = strS;
    char *p1 = strText;
    while (*p) {
        if (*p == eRus) *p1 = e1; else if (*p == e1Rus) *p1 = e2; else
            if (*p >= minRus && *p <= maxRus) {i = *p - minRus; *p1 = minR + i;} else *p1 = (char) *p;
        p1++;
        p++;
    }
}
Добавлено через 26 минут
после 18 строки надо вставить символ конца строки:
C++
1
*p1 = '\0';
0
xizix
0 / 0 / 0
Регистрация: 10.11.2017
Сообщений: 4
10.11.2017, 22:04 #12
Может немного не в тему, но прежде перелопатил гугл как только мог. Знаний как таковых в С++ нет, а хочется на ардуине проект запустить.
К примеру есть текст
§б§в§Ъ§Ю§Ц§в §д§Ц§Ь§г§д§С
Если использовать онлайн декодер, то показывает кодировку GB2312.
Не могу понять как использовать функцию выше для расшифровки этого текста, может поможете примерами в выводом в Serial?
0
10.11.2017, 22:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.11.2017, 22:04
Привет! Вот еще темы с решениями:

Перевести Unicode строку в ANSI
char label_ansi; wchar_t label_wide; sprintf_s (label_ansi, &quot;%ls&quot;,...

Перевод из unicode в ansi и utf8
Подскажите, пожалуйста, как перевести unicode строку в ansi и utf8? ...

Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF)
Есть следующий кусок кода: FILE* fp = fopen(&quot;G:\OPND1.txt&quot;, &quot;r&quot;); if...

ANSI или UNICODE
Всем привет!!! У меня возникла такая ситуация что использовать в WinApi...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

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