| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C++ Builder > Кодировка в C++ Builder 2010 |
| Автор: ipc 21.10.2010, 13:37 | ||
| Доброго времени суток, господа. Помогите, пожалуйста, разобраться с проблемой. Почему русский текст моим приложением понимается как абракадабра (не вопросики). Я заканчиваю курсовой проект, в котором часть мультиязычного функционала состоит в том, чтобы обращаться к удаленной базе данных. Для этого была выбрана кодировка utf8. На стороне сервера MySQL, PHP На стороне клиента Embarcadero Builder 2010 (с базовой Indy) Все таблицы MySQL, и поля в них, со сравнением utf8_general_ci. Код обращения на Билдере:
Неисключено, что тему кодировки я не до конца понимаю, потому как безрезультатно гуглю уже третьи сутки, а сроки безжалостно поджимают. Если я все правильно понимаю, то: - utf8 на то и такая громоздкая, чтобы в ней можно было передавать все символы большиства языков. - Builder и Delphi 2010, как объявлено, заточены для работы с юникодом. Из этого всего получается, что преобразовывать к локализации ansi мне не требуется, достаточно полученную юникодовскую строку подать, допустим, в мемо, а оно отобразит как надо. Или не так? P/s/ абракадабру я копипастнул в файл и открыл lister'ом, он отобразил русский текст если указать, что он в UTF-8. Подскажите, пожалуйста, в чем может быть ошибка, или куда копать, я уже, пожалуй, все перепробывал(( Заранее, спасибо! |
| Автор: Alexeis 21.10.2010, 14:37 |
| Билдер должен знать что к нему пришла строка в формате UTF8, только тогда он сможет корректно конвертировать ее в utf16 для отображения на windows контролах. Для таких строк предусмотрен тип UTF8String. Строка как набор байтов это RawString . При копировании в RawString не осуществляются ни какие преобразования. |
| Автор: ipc 21.10.2010, 15:04 | ||
| Спасибо, за такой быстрый ответ. Т.е. получается (подведу вышесказанные ответы), что у меня приходит строка utf8, а в мемо отображается в utf16. И надо конвертировать как-то в utf16 потому как билдер не понимает, что в мемо подается строка utf8. Так? Пробывал следующие конструкции :
не помогают((((( Как быть? |
| Автор: Alexeis 21.10.2010, 15:18 | ||
Ничего не нужно конвертировать, он сам все умеет, важно, чтобы изначально получить строку в правильном формате. Скорее всего в строке utf16 хранятся данные не соответствующие контейнеру. Значит нужно создать контейнер правильного типа(UTF8String), зарезервировать необходимую память и побайтово скопировать туда (например при помощи memcpy). После этого все операции будут корректными. |
| Автор: ipc 21.10.2010, 15:55 | ||||
Сделал следующее:
Результат не изменился..... Символы в контролле те же. |
| Автор: Alexeis 21.10.2010, 16:17 | ||||||||
Для начала соответствуют ли тут типы? Если нет то произойдет конвертация с потерей информации
Во-вторых чеза?
Где тут конструктор умеющий выделять длину?
В третьих почему начало объекта должно совпадать с началом строки? И почему размер памяти равен длине строки?
|
| Автор: ipc 21.10.2010, 18:45 | ||
| Да, типы соответствуют. Alexeis, спасибо, все исправил. Теперь:
Результат изменился, но теперь вместо привычной абракадабры в несколько предложений выдало всего несколько символов " \ ?" и все. Я что-то снова не то сделал? |
| Автор: oldcode 21.10.2010, 19:08 | ||
|
| Автор: ipc 21.10.2010, 19:55 |
| oldcode, не совсем понял, что ты хотел этим сказать) |
| Автор: Alexeis 21.10.2010, 20:20 |
| ipc, если там текст английский, то utf8 совпадает с ansi и его должно быть видно в отладчике. Нужно проверить что в самой первой строке правильный текст. |
| Автор: ipc 22.10.2010, 10:03 | ||
Alexeis,сделал, чтобы возвращался смешанный текст (сначала пара слов английского, затем русский).
В отдладчике srcStr показывает эту пару слов английского, затем ту же абракадабру. После memcpy dstStr равна первому символу из srcStr и символу конца строки. Т.е. исходный текст: "English text. Русский текст". srcStr: "English text. Р СѓСЃСЃРєРёР№ текст" dstStr: "E\0" |
| Автор: Platov 22.10.2010, 10:15 |
| Такой текст преобразуется туда и братно с помощью Utf8ToAnsi и AnsiToUtf8. |
| Автор: oldcode 22.10.2010, 10:15 |
| http://www.codeproject.com/KB/string/utfConvert.aspx |
| Автор: ipc 22.10.2010, 11:33 |
| Platov, Utf8ToAnsi я пробывал, как только появилась проблема. Эта функция возращает пустую строку(( К тому же, зачем мне в Ansi переводить, если контроллы в 2010 версии понимают в первую очередь юникод? |
| Автор: Platov 22.10.2010, 11:39 | ||
Попробуй!
У меня ведь работает. |
| Автор: Alexeis 22.10.2010, 11:49 | ||
Хм... что-то похоже неверно с источником. Проверил у себя помещаю uft8 в UnicodeString получаю не читаемый английский текст. И это правильно, потому что он рассматривает 2 символа как 1.
u8str - "english СЂСѓСЃСЃРєРёР№" s - { "湥汧獩胑菑臑臑뫐룐말ȀText=\"Фон" } Мои оба результата предсказуемы. Это значит что в StrStreamInc->DataString уже пострадавший текст от конвертации Ansi -> utf16 ; Indy ожидал встретить Ansi и записал буфер как Ansi, после чего сам произвел конвертацию в юникод и тем самым испортил данные. Можно попробовать следующий вариант. Убитый Utf8 в контейнере UTF16 сконвертить обратно в Ansi затем буфер данных Ansi скопировать в контейнер для UTF8. Но работать будет 50/50. Дело в том, что при порче данных запросто могут появиться символы не существующие в кодировке Ansi, поэтому при обратном преобразовании они заменяться на квадратики. Те же что имеют эквивалент восстановятся верно. Вердикт. Использовать другой способ который даст доступ к исходному буферу и не произведет порчу данных. |
| Автор: ipc 22.10.2010, 11:50 |
| ЕСТЬ!!!! Всем СПАСИБО, огромнейшее!!! Alexeis, в частности, за терпение и разъяснение. oldcode, очень полезная ссылка, решила проблему в раз! Добавлено через 4 минуты и 29 секунд Еще раз всем спасибо ребят Platov, Alexeis, oldcode. |
| Автор: oldcode 22.10.2010, 13:55 | ||
покажи, как переписАл на ВСВ, а то не вникал |
| Автор: ipc 22.10.2010, 15:57 | ||
Вот. Правда без Utf8ToAnsi все же не обошлось, а жаль, чувствую, это еще выйдет мне боком при парсинге.
|
| Автор: 0x00 26.10.2010, 15:12 |
| все не читал но скорее всего проблема на стороне скрипта. там надо чтонибудь типа (Java) request.setCharacterEncoding("UTF-8"); поставить |