Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Кодировка в C++ Builder 2010, Проблема с кодировкой UTF8 
V
    Опции темы
ipc
Дата 21.10.2010, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 21.10.2010

Репутация: 1
Всего: 1



Доброго времени суток, господа. Помогите, пожалуйста, разобраться с проблемой. Почему русский текст моим приложением понимается как абракадабра (не вопросики).

Я заканчиваю курсовой проект, в котором часть мультиязычного функционала состоит в том, чтобы обращаться к удаленной базе данных. Для этого была выбрана кодировка utf8.

На стороне сервера MySQL, PHP
На стороне клиента Embarcadero Builder 2010 (с базовой Indy) 

Все таблицы  MySQL, и поля в них, со сравнением utf8_general_ci.

Код обращения на Билдере:

Код

        // посылаемое значение
        TStringStream *StrStreamSend  = new TStringStream();
        // возращаемый ответ от сервера
        TStringStream *StrStreamInc  = new TStringStream();

        // параметры...
        StrStreamSend->WriteString("ID=1");        

        // запрос
        IdHTTPmain->Post("http://mysite.ru/catcher.php", StrStreamSend, StrStreamInc);
        // в этом месте на сервере происходит запрос  (SELECT `names`WHERE `ID`='1') 
        // и результат первой записи выводится через echo
        IdHTTPmain->Disconnect();

        // вот здесь абракадабра ((((
        Memo1->Text = StrStreamInc->DataString;


Неисключено, что тему кодировки я не до конца понимаю, потому как безрезультатно гуглю уже третьи сутки, а сроки безжалостно поджимают. Если я все правильно понимаю, то: 
   - utf8 на то и такая громоздкая, чтобы в ней можно было передавать все символы большиства языков. 
   - Builder и Delphi 2010, как объявлено, заточены для работы с юникодом. 
Из этого всего получается, что преобразовывать к локализации ansi мне не требуется, достаточно полученную юникодовскую строку подать, допустим, в мемо, а оно отобразит как надо. Или не так? 

P/s/ абракадабру я копипастнул в файл и открыл lister'ом, он отобразил русский текст если указать, что он в UTF-8.

Подскажите, пожалуйста, в чем может быть ошибка, или куда копать, я уже, пожалуй, все перепробывал((
Заранее, спасибо!
PM MAIL   Вверх
xvr
Дата 21.10.2010, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



UTF8 это способ кодировки Unicode символов (которые сами по себе 2х байтовые) в виде потока байтов. 
Цитата(ipc @  21.10.2010,  13:37 Найти цитируемый пост)
utf8 на то и такая громоздкая, чтобы в ней можно было передавать все символы большиства языков.
Она не громоздкая. Чистый английский текст в UTF8 останется как был - чистым английским текстом.

Цитата(ipc @  21.10.2010,  13:37 Найти цитируемый пост)
 Builder и Delphi 2010, как объявлено, заточены для работы с юникодом. 
Угу, причем в родной, Unicode'овской кодировке (т.е. 2х байтовыми символами). UTF8 в эту кодировку надо переводить явно (как именно не знаю, нету у меня 2010 Билдера)


PM MAIL   Вверх
Alexeis
Дата 21.10.2010, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Билдер должен знать что к нему пришла строка в формате UTF8, только тогда он сможет корректно конвертировать ее в utf16 для отображения на windows контролах. 
  Для таких строк предусмотрен тип UTF8String. Строка как набор байтов это RawString . При копировании в RawString не осуществляются ни какие преобразования.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
ipc
Дата 21.10.2010, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 21.10.2010

Репутация: 1
Всего: 1



Спасибо, за такой быстрый ответ.

Т.е. получается (подведу вышесказанные ответы), что у меня приходит строка utf8, а в мемо отображается в utf16. И надо конвертировать как-то в utf16 потому как билдер не понимает, что в мемо подается строка utf8. Так?

Пробывал следующие конструкции : 

Код

UTF8ToUnicodeString(StrStreamInc->DataString)
UTF8ToUnicodeString(UTF8String(StrStreamInc->DataString))
UTF8ToUnicodeString(UTF8Encode(StrStreamInc->DataString))


не помогают((((( Как быть?
PM MAIL   Вверх
Alexeis
Дата 21.10.2010, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Цитата(ipc @  21.10.2010,  16:04 Найти цитируемый пост)
И надо конвертировать как-то в utf16 потому как билдер не понимает, что в мемо подается строка utf8. Так?

  Ничего не нужно конвертировать, он сам все умеет, важно, чтобы изначально получить строку в правильном формате. Скорее всего в строке utf16 хранятся данные не соответствующие контейнеру. Значит нужно создать контейнер правильного типа(UTF8String), зарезервировать необходимую память и побайтово скопировать туда (например при помощи memcpy). После этого все операции будут корректными.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
ipc
Дата 21.10.2010, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 21.10.2010

Репутация: 1
Всего: 1



Цитата(Alexeis @ 21.10.2010,  15:18)
Значит нужно создать контейнер правильного типа(UTF8String), зарезервировать необходимую память и побайтово скопировать туда (например при помощи memcpy).


Сделал следующее:

Код

UnicodeString srcStr = StrStreamInc->DataString;
UTF8String *dstStr = new UTF8String(srcStr.Length());
memcpy((void *)dstStr, &srcStr, srcStr.Length());


Результат не изменился..... Символы в контролле те же.
PM MAIL   Вверх
Alexeis
Дата 21.10.2010, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Для начала соответствуют ли тут типы? Если нет то произойдет конвертация с потерей информации 
Код

UnicodeString srcStr = StrStreamInc->DataString;

Во-вторых чеза?
Цитата(ipc @  21.10.2010,  16:55 Найти цитируемый пост)
UTF8String *dstStr = new UTF8String(srcStr.Length());

Код

    __fastcall AnsiStringBase(): Data(0) {}
    __fastcall AnsiStringBase(const AnsiStringBase& src);
    __fastcall AnsiStringBase(const char* src, int codePage);
    __fastcall AnsiStringBase(const char* src, int byteLen, int codePage);
    __fastcall AnsiStringBase(const wchar_t* src, int numwchar, int codePage);
    __fastcall AnsiStringBase(const char16_t* src, int numChar16, int codePage);
    __fastcall AnsiStringBase(const char32_t* src, int numChar32, int codePage);

    __fastcall AnsiStringBase(double src, int codePage);
    __fastcall AnsiStringBase(wchar_t src, int codePage);
    __fastcall AnsiStringBase(const WideString &src, int codePage);
    __fastcall AnsiStringBase(const UnicodeString &src, int codePage);
#if !defined(_DELPHI_STRING_UNICODE)
    __fastcall AnsiStringBase(const AnsiString &src, int /*codePage*/): Data(0) {

Где тут конструктор умеющий выделять длину?
Код

UTF8String dstStr;
dstStr.SetLength(srcStr.Length() * sizeof(wchar_t));

В третьих почему начало объекта должно совпадать с началом строки? И почему размер памяти равен длине строки?
Код

memcpy(&dstStr[1], &srcStr[1], srcStr.Length() * sizeof(wchar_t));




--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
ipc
Дата 21.10.2010, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 21.10.2010

Репутация: 1
Всего: 1



Да, типы соответствуют.

Alexeis, спасибо, все исправил. Теперь: 
Код

    UnicodeString srcStr = StrStreamInc->DataString;

    UTF8String dstStr;
    dstStr.SetLength(srcStr.Length() * sizeof(wchar_t));

    memcpy(&dstStr[1], &srcStr[1], srcStr.Length() * sizeof(wchar_t));

Результат изменился, но теперь вместо привычной абракадабры в несколько предложений выдало всего несколько символов " \ ?" и все.

Я что-то снова не то сделал?
PM MAIL   Вверх
oldcode
Дата 21.10.2010, 19:08 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 8.10.2010

Репутация: 0
Всего: 0



Код

L"ID=1");        
L"http://mysite.ru/catcher.php"


Это сообщение отредактировал(а) oldcode - 21.10.2010, 19:20
PM MAIL   Вверх
ipc
Дата 21.10.2010, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 21.10.2010

Репутация: 1
Всего: 1



oldcode, не совсем понял, что ты хотел этим сказать)
PM MAIL   Вверх
Alexeis
Дата 21.10.2010, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



ipc, если там текст английский, то utf8 совпадает с ansi и его должно быть видно в отладчике. Нужно проверить что в самой первой строке правильный текст.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
ipc
Дата 22.10.2010, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 21.10.2010

Репутация: 1
Всего: 1



Alexeis,сделал, чтобы возвращался смешанный текст (сначала пара слов английского, затем русский). 

Код

UnicodeString srcStr = StrStreamInc->DataString;

В отдладчике srcStr показывает эту пару слов английского, затем ту же абракадабру.
После memcpy dstStr равна первому символу из srcStr и символу конца строки.

Т.е. исходный текст: "English text. Русский текст".
srcStr: "English text. Р СѓСЃСЃРєРёР№ текст"
dstStr: "E\0"
PM MAIL   Вверх
Platov
Дата 22.10.2010, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 23.7.2009

Репутация: 2
Всего: 2



Такой текст
Цитата(ipc @  22.10.2010,  10:03 Найти цитируемый пост)
"English text. Русский текст"


преобразуется туда и братно с помощью Utf8ToAnsi и AnsiToUtf8.

PM MAIL   Вверх
oldcode
Дата 22.10.2010, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 8.10.2010

Репутация: 0
Всего: 0



PM MAIL   Вверх
ipc
Дата 22.10.2010, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 21.10.2010

Репутация: 1
Всего: 1



Platov, Utf8ToAnsi я пробывал, как только появилась проблема. Эта функция возращает пустую строку((
К тому же, зачем мне в Ansi переводить, если контроллы в 2010 версии понимают в первую очередь юникод?
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0992 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.