Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.12.2015, 18:00   #11
taras-proger
Подтвердите свой е-майл
 
Регистрация: 12.11.2014
Сообщений: 470
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Это размер в байтах входной строки в буфере. Если строка нуль-терминальная ставьте -1.
Всей строки?Но тогда:
1. Буфер для результата преобразования принципиально не резервируем.
2. Как закрыть в класс функцию, принимающую указатель на результат? Или как иначе защититься от невалидного указателя на результат? Сейчас у меня есть класс TUTF8 отдельного символа с констуркторами, принимающими char, wchar_t и char32_t и с оператором-членом приведения к char32_t. Внутренне представление - UTF-8 в резервированном private-массиве Data на 7 байт, за кодом единственного символа идёт нулевой байт. Есть дружественный потоковый класс, а в нём оператор-член вывода в поток, выводящий в поток именно этот массив. Каждый символ строки приводится к TUTF8 и сразу выводится его Data. А как быть с целой строкой? Терминальный ноль завершает всю строку. На паскале я бы написал локальную функцию и не мучался. А на сях? Икладить её в ручную?
taras-proger вне форума Ответить с цитированием
Старый 02.12.2015, 19:30   #12
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от taras-proger Посмотреть сообщение
Всей строки?Но тогда:
1. Буфер для результата преобразования принципиально не резервируем.
MultiByteToWideChar и WideCharToMultiByte могут вернуть нужный размер для целой строки.
Берите нужный размер да выделяйте память сколько угодно.

В плане защиты указателей и/или защиты от неверных указателей все просто - не использовать указатели, вместо них использовать ссылки на класс, который получит результат, в вашем случае это будет какая-то разновидность string класса, либо прямо возвращать класс как результат вызова.

Последний раз редактировалось waleri; 02.12.2015 в 19:37.
waleri вне форума Ответить с цитированием
Старый 02.12.2015, 20:00   #13
taras-proger
Подтвердите свой е-майл
 
Регистрация: 12.11.2014
Сообщений: 470
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
в вашем случае это будет какая-то разновидность string класса, либо прямо возвращать класс как результат вызова.
Энто какая же? Строка оболочек над UTF-8 подходит только при посимвольном преобразовании, так как при вызове библиотечной функции для целой строки она возвращает неравномерный UTF-8. В самой функции что ли new применить и выдать указатель? Так потом его освобождать снаружи, тоже плохо.

Цитата:
Сообщение от waleri Посмотреть сообщение
MultiByteToWideChar и WideCharToMultiByte могут вернуть нужный размер для целой строки.
Берите нужный размер да выделяйте память сколько угодно.
Динамически. При этом new может вернуть nullptr. И это вместо двадцати байт на стеке с учётом и одиннацати байт на все буфера, и счётчика индекса символа, и переменной для длины строки, и переменной для длины кода символа. Код функции тоже не в куче и размер его достаточно мал и известен.

Последний раз редактировалось Stilet; 03.12.2015 в 09:56.
taras-proger вне форума Ответить с цитированием
Старый 02.12.2015, 22:39   #14
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

если new вернет nullptr то у меня для вас плохие новости.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 03.12.2015, 00:33   #15
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,755
По умолчанию

По существу заданных вопросов.

Цитата:
Сообщение от taras-proger Посмотреть сообщение
Требуется получить std::u32string в кодировке UTF32. Желательно без промежуточных нуль-терминальных строк в иных кодировках.
Поскольку Windows не имеет встроенной поддержки UTF-32, без промежуточного буфера UTF-16 не обойтись. Его можно выделить в стеке, а потом перекодировать строку кусками. Функции MutiByteToWideChar задается размер приемника, так что больше она не запишет.

Промежуточный буфер на 1024 символа по-любому лучше, чем гонять вызовы MultiByteToWideChar на каждый символ. Функция это не быстрая, на больших объемах просадка скорости будет в разы.

Цитата:
Сообщение от taras-proger Посмотреть сообщение
Есть ли гарантия, что в CP_ACP каждый символ занимает ровно 1 байт?
Такой гарантии однозначно нет. В азиатских локализациях в CP_ACP может стоять и Shift-JIS, и Big5, и другие кодировки с переменной длиной символа.

Цитата:
Сообщение от taras-proger Посмотреть сообщение
И есть ли гарантия, что он влезет в UTF16?
В UTF-16 влезет всё, поскольку все кодировки Юникода взаимно-обратимы. Для "верхнего Юникода" есть суррогатные пары, как уже тут говорили. Суррогатные пары корректно работают на системном уровне начиная с XP (может быть только с XP SP2). Если тебе нужен корректный UTF-32, будешь раскодировать их вручную, на Википедии есть алгоритм.

Есть также особая четырехбайтовая китайская кодировка GB18030, в которой теоретически могут быть иероглифы, требующие суррогатных пар. Я не настолько глубоко влезал, поэтому точно сказать не могу, могу и ошибаться. GB18030 также поддерживается начиная с XP. Из-за нестандартности у нее куча особенностей, которые описаны в ремарках на MSDN.
Vapaamies вне форума Ответить с цитированием
Старый 03.12.2015, 09:35   #16
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
а потом перекодировать строку кусками.
Та еще головная боль...
Например, берем входной ACP буфер размер в N байт и вызываем MultiByteToWideChar и функция возвращает "я сконвертировала 16 символов". Внимание, вопрос, сколько байт нужно пропустить в исходном буфере для конвертации следующих 16 символов?

Проще получить нужную длинну и выделить весь буфер целиком и сконвертировать все в один прием. Как ни верти, выделять буфер все равно надо.
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как преобразовать строку в название константу или её индификатор androidz Общие вопросы Delphi 10 27.02.2014 21:33
Как сохранить область на странице вhtml или как картинку или в pdf ? xxxsas PHP 0 10.12.2011 12:02
Как сделать MD5 строки в utf8? Anfall Общие вопросы Delphi 4 04.08.2011 16:54
Http.Get, Парсинг UTF8, знак - отображается как ? Как декодировать? XerSon Работа с сетью в Delphi 6 10.02.2011 08:37
Как получить адрес String строки или преобразовать String madboy4ik Общие вопросы по Java, Java SE, Kotlin 6 15.01.2010 11:57