![]() |
|
|
![]()
|
|
| cdmmon |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 24.5.2013 Репутация: нет Всего: нет |
Привет всем!
Нужна помощь. Пишу приложение в eclipse на с++. В данном приложении делаю запрос на сайт и получаю ответ (JSON), в виде стоки UTF-8. С сайта уходит "пйъя"("\u043f\u0439\u044a\u044f") Вот сюда приходит колбэк: int parse_string(void * ctx, const unsigned char * stringVal, unsigned int stringLen) Используемое UI не поддерживает UNICODE (UTF8). Вывожу содержимое в консоль: parse_string-пйÑ?Ñ?, string length-8 (получается по 2 байта) , дальше кастую к инту и вывожу в консоль: 208, 191, 208, 185, 209, 138, 209, 143 Кто может растолковать, как строится эта строка? а то ищу, читаю. не могу догнать пока.. Спасибо |
|||
|
||||
| tzirechnoy |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 1 Всего: 16 |
||||
|
||||
| cdmmon |
|
||||||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 24.5.2013 Репутация: нет Всего: нет |
ну это первое, что я прочитал. а можешь пояснить? Добавлено через 6 минут и 26 секунд
на сколько я понял их вики - если символ в UTF-8 имеет один байт, то он соответствует таблице ASCII, если имеет 2 байта, как киррилическая буква "п" в utf-8, то что за что отвечает? |
||||||
|
|||||||
| cdmmon |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 24.5.2013 Репутация: нет Всего: нет |
так что? никто?
вот что я не могу понять: 041A (по юникоду 1050) - большая кириллическая «К» - выдаст нам 2 байта - D0 9A (при трех байтах будет - E0 90 9A), где D0 - это 11010000, две первые еденицы говорят о том, что по этому символу будет два байта (а третья еденица для чего?), и второй байт - 9А это 10011010, где 10 - это обозначение того, что это байт самого символа, т.е. 154? первый старший бит считается? если это 154, тогда в какой таблице 154 равен большой кириллической букве "К"? Добавлено через 7 минут и 31 секунду Тоже самое и с моими "пйъя", которые приходят с сайта. т.е. parse_string-208, 191, 208, 185, 209, 138, 209, 143 (string length-8 - по 2 байта), где 208 = 11010000 (11 - значит два байта, а что за третья еденица?), 191 - это буква "п"? Так же и с буквой "й" - 208 (2 байта) + 185(буква "й"?). А дальше? 209! - это уже 11010001 - эта зачем единица тут? Это сообщение отредактировал(а) cdmmon - 25.4.2014, 00:26 |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
Младшие биты первого байта - это старшие биты Unicode. В младших битах второго байта (и третьего, если есть) хранятся младшие биты Unicode. Их нужно собрать и склеить в одно целое (операции & и <<)
Добавлено через 6 минут и 6 секунд PS: как я понял, твой колбэк вызывается из Java. В таком случае правильнее попроить Java перекодировать твою строку. Как это сделать, спрашивай на форуме Java. |
|||
|
||||
| cdmmon |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 24.5.2013 Репутация: нет Всего: нет |
Разобрался, как перевести в Юникод: (вдруг пригодится кому..)
берем за основу следующие вводные данные: const byte* src (это указатель на нашу строку), size_t count (это длина нашей строки, т.е. для русского по 2 байта на каждый символ, при моих 4-х символах (пйъя) размер равен 8-ми) char output[count + 1]; //создаем массив + 1, запишем туда конец строки) int ctr = 0; //счетчик нашей новой строки while(*src != 0) { //тут все понятно if((*src & 0x80) == 0){ /*проверяем, если текущий байт меньше 128, значит просто берем значение тупо из ASCII*/ //ASCII output[ctr++] = *src++; }else if((*src & 0xE0) == 0xC0){ /*проверяем первый байт на то, что там у нас стоят две единицы, что готорит о том, что на текущий символ задействовано 2 байта, т.е. к примеру для симовла"п" (208) первый байт - это 1101 0000 (208 или 0xD0), где первые две единицы это инфа о том, что у нас два байта, третья единица нужна будет для перевода в Юникод */ // 2 байта byte b1 = *src++; //запоминаем первый байт byte b2 = *src++; //и второй байт if((b2 & 0xC0) != 0x80) /*проверяем на ошибку во втором байте - второй байт в двоичной ситеме всегда должен начинатся с 10 (1000 0000 = 0х80). В ином случае - ошибка. */ break; output[ctr++] = ((b1 & 0x1F) << 6) | (b2 & 0x3F);/* приводим значение двух байт к таблице юникода: в первых скобках убираем две первые единицы, т.к. они нужны только для информирования о кол-ве байт для текущего символа, и результат сдвигаем. получается к примеру для буквы "п" первый байт равет 208 (1101 0000 или D0), где 0xD0 & 0x1F (1F = 0001 1111) - откидывается первые три цифны - 110, и получается 0001 0000, после здвига получается 0100 0000 0000 = 1024. Во вторых скобках обрабатываем байт, в котором содержится код символа: для буквы "п" это 191 (1011 1111 или 0xBF). Дальше откидываем первые две цифры (они всегда равны 10 для второго байта) - BF & 3F (0011 1111) = 0011 1111 (3F). Дальше складываем результат ообеих скобок: 1024 + 63 = 1087 - в таблице юникода это и есть символ "п"*/ }else if((*src & 0xF0) == 0xE0){//аналогично обрабатываем 3 байта // 3 bytes byte b1 = *src++; byte b2 = *src++; byte b3 = *src++; if((b2 & 0xC0) != 0x80) break; if((b3 & 0xC0) != 0x80) break; output[ctr++] = ((b1 & 0x0F) << 12) | ((b2 & 0x1F) << 6) | (b3 & 0x3F); }else{ output[ctr] = '\0'; return output; } } output[ctr] = '\0';//по окончанию проверки строки, записываем в массив конец строки. ВСЕ! Добавлено @ 08:32
да, спс. это я уже понял. по поводу колбэка - это отдельная либа под с++. сецчас перевести в юникод - у меня получилось. Но у меня не поддерживается юникод. теперь не могу сообразить, как символ "п" из таблицы юникода, равный 1087 (43F) перевести в ASCII, равный 239? Есть идеи? Это сообщение отредактировал(а) cdmmon - 25.4.2014, 08:38 |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
Если нет официальной поддержки кодировок, переводить можно так:
|
|||
|
||||
| cdmmon |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 24.5.2013 Репутация: нет Всего: нет |
спасибочки. Ща протестим.. )) |
||||
|
|||||
| cdmmon |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 24.5.2013 Репутация: нет Всего: нет |
У тебя обшибчка.. надо вынести переменную int i из цикла (объявить ее перед циклом), чтобы она была доступна после окончания действия цикла.. Смысл понятен. Но теперь есть другой вопрос. Может есть идеи, как можно заполнить строку переменной cp1251 в соответствие от разного типа кодировок? А то вручную все вбивать не охота. И может есть идеи, как определить мне, в какую кодировку мне пытаться переводить мой УТФ? т.е. в ср1251, или 1253...? Потому что по идеи мне может прийти туда и другие кодировки.. Добавлено через 1 минуту и 40 секунд я не могу себе представить, как мне заполнить переменную cp1251 - там в ср1251 столько левых символов между теми символами, которые мне нужны. их либо надо чем то заполнить, либо все таки как то ввести туда. Но как? |
||||
|
|||||
| math64 |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
я вводил код на лету. естественно, есть ошибка.
Если нужно возиться с разными кодировками, возьмите готовую библиотеку, например libiconv. |
||||
|
|||||
| cdmmon |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 24.5.2013 Репутация: нет Всего: нет |
Вот так выглядет мой вариант для ср1251:
Первые 64 бита ковырял вручную из ворда, так что может где-то и не угадал, но для меня эти символы не так важны.. Добавлено через 32 секунды
Спасибо, почитаю.. |
||||
|
|||||
![]()
|
| Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |