+ Ответить в теме
Страница 1 из 4
1 2 3 4 ПоследняяПоследняя
Показано с 1 по 10 из 37

Тема: Не получается преобразование нуль-терминальной UTF8 в std::wstring

  1. #1
    Недохакер system architect Сионист is an unknown quantity at this point Аватар для Сионист
    Регистрация
    31.03.2014
    Сообщений
    1,078
    Вес репутации
    0

    По умолчанию Не получается преобразование нуль-терминальной UTF8 в std::wstring

    Есть указатель на char, в котором лежит нуль-терминальная строка в UTF8. Пока в строке только латиница, или только кириллица, преобразование происходит правильно. Но как только смешаны двубайтные символы с однобайтными, начинаются странности. Например, строка равна "Система>Как Вас зовут?" (префикс опущен, но это UTF-8),
    Код cpp:
    1. L16=MultiByteToWideChar(CP_UTF8, 0, Utf8, L8, nullptr, 0);
    Пока в строке только латиница, или только кириллица, L8 равна 41 (правильно), но L16 вдруг 27, дальше
    Код cpp:
    1. MultiByteToWideChar(CP_UTF8, 0, Utf8, L8, Utf16, L16);
    2. return std::wstring(Utf16);
    , 26 символов, но TextOut пишет слово L"Система" и потом квадратик вместо символа L'>' и дальше символов нет.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.

  2. По умолчанию

     
    Хотите избавиться от рекламы? Зарегистрируйтесь
  3. #2
    Недохакер system architect Сионист is an unknown quantity at this point Аватар для Сионист
    Регистрация
    31.03.2014
    Сообщений
    1,078
    Вес репутации
    0

    По умолчанию Re: Не получается преобразование нуль-терминальной UTF8 в std::wstring

    Проблема решена посимвольным преобразованием. Конкатенация уже преобразованных строк работала правильно с самого начала, но только если сами строки преобразованы правильно. Смешение двубайтных и однобайтных символов при конкатенации значения не имело.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.

  4. #3
    Moderator Куратор
    system architect
    Absurd is on a distinguished road
    Регистрация
    26.02.2004
    Адрес
    Pietari, Venäjä
    Возраст
    38
    Сообщений
    1,213
    Вес репутации
    17

    По умолчанию Re: Не получается преобразование нуль-терминальной UTF8 в std::wstring

    А немного подумать нельзя было?

    Код cpp:
    1. template<std::size_t BUFF_SIZE = 0x100>
    2.   std::wstring toWideChar(const char* src, UINT codepage = CP_UTF8)
    3. {
    4.   enum { MaxStackBuffSizeInWchars = BUFF_SIZE / sizeof(wchar_t) };
    5.   int srcLengthInBytes = static_cast<int>(std::strlen(src));
    6.   int lengthInWideChars = MultiByteToWideChar(codepage, 0, src, srcLengthInBytes, NULL, 0);
    7.   if (lengthInWideChars <= MaxStackBuffSizeInWchars) {
    8.     wchar_t buff[MaxStackBuffSizeInWchars];
    9.     MultiByteToWideChar(codepage, 0, src, srcLengthInBytes, buff, lengthInWideChars);
    10.     return std::wstring(buff, lengthInWideChars);
    11.   } else {
    12.     auto buff = std::make_unique<wchar_t[]>(lengthInWideChars);
    13.     MultiByteToWideChar(codepage, 0, src, srcLengthInBytes, buff.get(), lengthInWideChars);
    14.     return std::wstring(buff.get(), lengthInWideChars);
    15.   }
    16. }
    2B OR NOT(2B) = FF

  5. #4
    Недохакер system architect Сионист is an unknown quantity at this point Аватар для Сионист
    Регистрация
    31.03.2014
    Сообщений
    1,078
    Вес репутации
    0

    По умолчанию Re: Не получается преобразование нуль-терминальной UTF8 в std::wstring

    И что это?
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.

  6. #5
    Moderator Куратор
    system architect
    Absurd is on a distinguished road
    Регистрация
    26.02.2004
    Адрес
    Pietari, Venäjä
    Возраст
    38
    Сообщений
    1,213
    Вес репутации
    17

    По умолчанию Re: Не получается преобразование нуль-терминальной UTF8 в std::wstring

    Преобразование нуль-терминальной UTF8 в std::wstring.

    Код cpp:
    1. std::wstring ws = toWideChar("Шалом Израиль"); //Подразумевается что исходный код сохранен в UTF8
    2B OR NOT(2B) = FF

  7. #6
    Недохакер system architect Сионист is an unknown quantity at this point Аватар для Сионист
    Регистрация
    31.03.2014
    Сообщений
    1,078
    Вес репутации
    0

    По умолчанию Re: Не получается преобразование нуль-терминальной UTF8 в std::wstring

    1. Начнём с не понятного буферсайза. С какого потолка он вообще берётся?
    2. Каков смысл этого енама?
    3. Зачем здесь уникуй?
    4. Где и как в ветви else выделяется память для результата преобразования?
    5. А освобождается она где и как?
    Последний раз редактировалось Сионист; 13.12.2015 в 13:48.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.

  8. #7
    Moderator Куратор
    system architect
    Absurd is on a distinguished road
    Регистрация
    26.02.2004
    Адрес
    Pietari, Venäjä
    Возраст
    38
    Сообщений
    1,213
    Вес репутации
    17

    По умолчанию Re: Не получается преобразование нуль-терминальной UTF8 в std::wstring

    Начнём с не понятного буферсайза. С какого потолка он вообще берётся
    А его можно не трогать. Там прописан дефолт - 256 байт, то есть для строк чья длина меньше 256 байт динамическая память вообще не выделяется. Преобразование происходит в стеке. Если больше 256 байт, он создает временный массив в хипе.

    Каков смысл этого енама
    Это внутренняя константа внутри функции. Ее область видимости ограничена функцией. Вероятно можно использовать constexpr или что-то в этом роде.

    Зачем здесь уникуй
    Чтобы удалить временный массив после выхода из функции, очевидно.

    Где и как в ветви else выделяется память для результата преобразования
    Это делает make_unique.

    А освобождается она где и как
    Деструктор unique_ptr

    У меня сохранился предыдущий вариант, который делает обратную трансформацию и не использует хип никогда вообще, но требует наличия непортируемой функции _alloca. Можно переписать toWideString в таком же стиле.

    Код cpp:
    1. std::string toMultibyte(const wchar_t* src, UINT codepage = CP_UTF8)
    2. {
    3.   int wcharCount = static_cast<int>(std::wcslen(src));
    4.   int buffSize = WideCharToMultiByte(codepage, 0, src, wcharCount, NULL, 0, NULL, NULL);
    5.   char* buff = static_cast<char*>(_alloca(buffSize));
    6.   WideCharToMultiByte(codepage, 0, src, wcharCount, buff, buffSize, NULL, NULL);
    7.   return std::string(buff, buffSize);
    8. }
    Последний раз редактировалось Absurd; 13.12.2015 в 14:44.
    2B OR NOT(2B) = FF

  9. #8
    Недохакер system architect Сионист is an unknown quantity at this point Аватар для Сионист
    Регистрация
    31.03.2014
    Сообщений
    1,078
    Вес репутации
    0

    По умолчанию

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

    Цитата Сообщение от Absurd Посмотреть сообщение
    А его можно не трогать. Там прописан дефолт - 256 байт, то есть для строк чья длина меньше 256 байт динамическая память вообще не выделяется.
    С какого потолка этот дефолт списан и зачем?

    Цитата Сообщение от Absurd Посмотреть сообщение
    Чтобы удалить временный массив после выхода из функции, очевидно.
    И как это удаление соотносится с уникальностью значений?

    Это делает make_unique.

    А освобождается она где и как
    Деструктор unique_ptr
    Не понял. Нельзя ли по подробней?
    Последний раз редактировалось Romeo; 14.12.2015 в 11:09.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.

  10. #9
    Moderator Куратор
    system architect
    Absurd is on a distinguished road
    Регистрация
    26.02.2004
    Адрес
    Pietari, Venäjä
    Возраст
    38
    Сообщений
    1,213
    Вес репутации
    17

    По умолчанию Re: Не получается преобразование нуль-терминальной UTF8 в std::wstring

    Цитата Сообщение от Сионист Посмотреть сообщение
    Ну локальные типы от глобальных я отличаю без посторонней помощи. Вопрос не в этом, а в назначении.
    Назначение описано в названии константы.
    Если интересует зачем я вычисляю размер буфера в широких чарах из параметра шаблона,
    то причина в том что у этой функции есть обратная и у нее промежуточный буфер не в чарах а байтах.
    Чтобы иметь общий вид у обоих функций размер буфера задается в байтах.

    Код cpp:
    1. template<std::size_t BUFF_SIZE = 0x100>
    2.   std::string toMultibyte(const wchar_t* src, UINT codepage = CP_UTF8)
    3. {
    4.   int wcharCount = static_cast<int>(std::wcslen(src));
    5.   int buffSize = WideCharToMultiByte(codepage, 0, src, wcharCount, NULL, 0, NULL, NULL);
    6.   if (buffSize <= BUFF_SIZE) {
    7.     char buff[BUFF_SIZE];
    8.     WideCharToMultiByte(codepage, 0, src, wcharCount, buff, buffSize, NULL, NULL);
    9.     return std::string(buff, buffSize);
    10.   } else {
    11.     auto buff = std::make_unique<char[]>(buffSize);
    12.     WideCharToMultiByte(codepage, 0, src, wcharCount, buff.get(), buffSize, NULL, NULL);
    13.     return std::string(buff.get(), buffSize);
    14.   }
    15. }

    Цитата Сообщение от Сионист Посмотреть сообщение
    С какого потолка этот дефолт списан и зачем?
    Если не устраивает дефолт размер можно передать явно через параметр шаблона.
    Но это оптимизация. Функция-то совершенно корректно обрабатывает строки любой длины.
    Только длинные строки - медленнее и с привлечением дополнительной памяти.
    Что считать длинной строкой - конфигурируется.

    Цитата Сообщение от Сионист Посмотреть сообщение
    И как это удаление соотносится с уникальностью значений?
    unique_ptr - уникальный указатель, а не значение.

    Цитата Сообщение от Сионист Посмотреть сообщение
    Деструктор unique_ptr
    Не понял. Нельзя ли по подробней?
    Деструктор unique_ptr делает delete[] для массивов, ничего непонятного тут нет
    2B OR NOT(2B) = FF

  11. #10
    Недохакер system architect Сионист is an unknown quantity at this point Аватар для Сионист
    Регистрация
    31.03.2014
    Сообщений
    1,078
    Вес репутации
    0

    По умолчанию

    Цитата Сообщение от Absurd Посмотреть сообщение
    Назначение описано в названии константы.
    Какой константы? У Вас их вообще нет.

    Цитата Сообщение от Absurd Посмотреть сообщение
    Если не устраивает дефолт размер можно передать явно через параметр шаблона.
    А где его вообще брать?

    Цитата Сообщение от Absurd Посмотреть сообщение
    unique_ptr - уникальный указатель, а не значение.
    А где там вообще ptr то?

    Цитата Сообщение от Absurd Посмотреть сообщение
    Деструктор unique_ptr делает delete[] для массивов, ничего непонятного тут нет
    А где массив?
    Последний раз редактировалось Romeo; 14.12.2015 в 11:10.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.

+ Ответить в теме
Страница 1 из 4
1 2 3 4 ПоследняяПоследняя

Похожие темы

  1. не получается переехать на IIS
    Нужна помощь по перенсу CMS с Apache на IIS. Для корректной работы CMS необходима поддержка rewrite mode. IIS его по умолчанию не поддерживает,...
    от Luca в разделе Apache, IIS...
  2. UTF8 to Win-1251
    Понимаю, что по этому поводу написано множество, однако... На самом обычном ASP (без dotNet) нужно преобразовать строку из GET запроса, получаемого...
    от Pervoklasnik в разделе Perl, PHP, ASP ...
  3. QueryInterface - не получается
    Есть такая штука: Frames:=WebBrowser.OleObject.Document.Frames; for i:=0 to Frames.Length-1 do If Frames.item(i).name='...' then ...
    от Blood_Magic в разделе Delphi и Pascal
  4. UTF8->ANSI
    Как перевести из кодировки UTF8 в ANSI. Причём вот есть код: WCHAR names1[30]; WCHAR names[] = L"Привет"; const int nSize =...
    от Alezis в разделе C и C++
  5. MySql и UTF8 и много чего ещё...
    Люди научите. Скачал недавно MySQL 4.1.12a. Там говориться что чарсет может быть UTF8. Мне он надо чтоб поддерживать кирилицу. Вроде в...
    от Alezis в разделе SQL

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения