Не получается приведение

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

WinMain писал(а):И ты считаешь это удачным решением задачи? Если строку в виде std::string наращивать посимвольно, то это приведёт к жудким тормозам при выполнении программы. На коротких строках это может и незаметно будет, но на более длинных текстах программа будет просто умирать.
А как же тогда защититься от нулевых байтов в UTF-8? Ведь первый из них будет принят за терминальный. Или в этом коде запрещены нулевые байты?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Romeo писал(а):Не работает с кириллицей. Вместо русских букв будут вставлены усечённые до одного байта ASCII символы с неожиданным значением.
Нифига подобного. Работает и с вязью, и с кириллицей и ничего не усекается, что показывают и тесты, и элементарнейший анализ.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Нифига подобного. Работает и с вязью, и с кириллицей и ничего не усекается, что показывают и тесты, и элементарнейший анализ.
Кириллица, плохой пример. Но можно подобрать символы, которые будет с нулевым байтом.
А как же тогда защититься от нулевых байтов в UTF-8? Ведь первый из них будет принят за терминальный. Или в этом коде запрещены нулевые байты?
Если ты защитишься от нулевых байтов путём их удаления (как у тебя сейчас сделано), то ты исковеркаешь текст. Нулевые байты нужно оставлять, они тоже несут смысловую нагрузку в UTF.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

В кодировке UTF-8 нет нулевых байтов между символами (кроме последнего в конце строки).
В отличие от обычной UNICODE-строки, где каждый символ кодируется строго двумя байтами, в кодировке UTF-8 символы латиницы (с кодом до 127) кодируются одним байтом, а символы других алфавитов - двумя или четырьмя байтами. И ни один из этих байтов не должен быть нулевым. К сведению: в кодировке UTF-8 буква "Ё" кодируется четырьмя! байтами.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Romeo писал(а):Если ты защитишься от нулевых байтов путём их удаления (как у тебя сейчас сделано), то ты исковеркаешь текст. Нулевые байты нужно оставлять, они тоже несут смысловую нагрузку в UTF.
У меня совсем не так сделано, я как раз копирую каждый байт.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

WinMain писал(а):В отличие от обычной UNICODE-строки, где каждый символ кодируется строго двумя байтами, в кодировке UTF-8 символы латиницы (с кодом до 127) кодируются одним байтом, а символы других алфавитов - двумя или четырьмя байтами.
При этом первый байт префиксный и заведомо ноля не содержит, так как признак следующего байта - первый больше 127. А второй может быть нулевым? Или третий? Или четвёртый?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

WinMain писал(а):В кодировке UTF-8 нет нулевых байтов между символами (кроме последнего в конце строки).
В отличие от обычной UNICODE-строки, где каждый символ кодируется строго двумя байтами, в кодировке UTF-8 символы латиницы (с кодом до 127) кодируются одним байтом, а символы других алфавитов - двумя или четырьмя байтами. И ни один из этих байтов не должен быть нулевым. К сведению: в кодировке UTF-8 буква "Ё" кодируется четырьмя! байтами.
Похоже мои интуитивные знания UTF-8 спутались со стандартом UTF-16. Если внутренних нулей не бывает, то и подход с вектором символов, ровно как и побайтное копирование, не нужны.
Сионист писал(а):При этом первый байт префиксный и заведомо ноля не содержит, так как признак следующего байта - первый больше 127. А второй может быть нулевым? Или третий? Или четвёртый?
Я только что внимательно изучил стандарт UTF-8. Судя по всему третий и четрвёртый тоже не могут быть нулевыми.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Код: Выделить всё

int main()
{
 std::string s="";
 s+='\0';
 s+='\0';
 s+='\0';
 s+='\0';
 s+='\0';
 s+='\0';
 std::cout<<s.length()<<std::endl;
 return 0;
}
вывело 6, а if под циклом не валяется, так что пропуском нулевых байт у меня не воняет.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Прочитал по ссылке, там у всех байтов префиксы, начинающиеся с единичного бита, так что нулевых быть ещё и не может.

Код: Выделить всё

std::string                                 WStringToUtf8                             (const
                                                                                       std::wstring                     &s                 )
{
 char        *Buffer;
 size_t       BufferSize;
 std::string  Result="";
 if (!s.empty())
 {
  BufferSize=WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.length(), NULL, 0, NULL, NULL);
  Buffer=new char[BufferSize]+1;
  if (Buffer!=NULL)
  {
   WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.length(), Buffer, BufferSize, NULL, NULL);
   Buffer[BufferSize]=0;
   Result=Buffer;
   delete [] Buffer;
  }
 }
 return Result;
}
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Decoder
Сообщения: 308
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

К сведению: в кодировке UTF-8 буква "Ё" кодируется четырьмя! байтами.
Так вот почему проект "Ё-мобиль" у Михаила Прохорова не состоялся - не ту кодировку использовали. :-)

А вообще-то данная тема уже когда-то поднималась на форуме.
Вот ссылка на неё.
Поумнеть несложно, куда труднее от дури избавиться.
Ответить