Re[8]: C++ и UTF8
От: gegMOPO4  
Дата: 27.10.11 13:00
Оценка:
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Да неужели?! В UTF-8 128 символа (в число которых входят наиболее частые) кодируются одним байтом. В UTF-16 каждый символ размазывается по нескольким байтам.
U>имелось в виду другое: std::basic_string<wchar_t> под виндой подходит для хранения UTF16, в таком случае в один wchar_t влезает бОльше инфы и размазать юникодные символ по двум wchar_t становится сложнее =)

Это нашим узкоглазым братьям расскажите.

А американцу что std::basic_string<char>, что std::basic_string<wchar_t> — всё равно. Т.е. не всё равно, в последнем случае будет ныть из-за расхода памяти.
Re[3]: C++ и UTF8
От: okman Беларусь https://searchinform.ru/
Дата: 27.10.11 13:03
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Ну и что? Поскольку UTF-8 совместима с ASCII и обладает ещё рядом замечательных свойств, ничто не мешает использовать std::string как контейнер. А наличие ряда специализированных функций для работы со строками делает его предпочтительнее std::vector<char>.


Зачем писать (отлаживать, тестировать) специализации, когда есть готовые библиотеки ?
Вот чего я не понимаю.

MOP>Какой результат вам нужен? Результат std::string::length — A count of the number of char-like objects (т.е. char в данном случае) currently in the string. Иными словами — количество байт в представлении UTF-8.


Я думаю, что Вы лукавите.
Когда мы вызываем string.length, мы хотим длину строки в символах, а не каких-то char-like объектов.

MOP>Да практически все будут работать. Какие не? Нужно только помнить, что std::string::length возвращает не количество символов, а pos — смещение, а не номер символа.


Как на счет строковых итераторов и алгоритмов, работающих со строками ?
Что передавать аргументом string::find_first_of ?

MOP>Только тогда, когда вам действительно нужны возможности ICU. Во многих случаях можно обойтись без.


Не спорю.
Re[6]: C++ и UTF8
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 27.10.11 13:07
Оценка:
Здравствуйте, sidorov18, Вы писали:

S>что значит переводить?

WinAPI вроде как работает в UCS-2. Как минимум, это ограничивает набор символов 65536-ю символами. Но все равно необходимо перевести из UTF-16 в UCS-2. Некоторые кроссплатформенные либы принимают все-таки UTF-8. Ну и под другие OS UTF-8 нативнее.


S>
S>"Василий"//L"Василий"
S>


S>вот так переводить?

S>решается макросом _T()

А тогда вопрос, как макрос _T узнает кодировку, в которой набран текст?
Re[5]: C++ и UTF8
От: okman Беларусь https://searchinform.ru/
Дата: 27.10.11 13:11
Оценка:
Здравствуйте, uzhas, Вы писали:

U>заметил, что беседа крайне непродуктивна


Это потому, что надо уметь признавать свои ошибки.
Как это делаю я.
Re[7]: C++ и UTF8
От: okman Беларусь https://searchinform.ru/
Дата: 27.10.11 13:16
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>В UTF-8 128 символа (в число которых входят наиболее частые) кодируются одним байтом.


Китайцы с Вами бы не согласились (см. выделенное).
Re[7]: C++ и UTF8
От: okman Беларусь https://searchinform.ru/
Дата: 27.10.11 13:16
Оценка:
Здравствуйте, Mystic, Вы писали:

M>А тогда вопрос, как макрос _T узнает кодировку, в которой набран текст?


Такие вещи, как правило, настраивается в опциях сборки проекта.
Re[6]: C++ и UTF8
От: gegMOPO4  
Дата: 27.10.11 13:21
Оценка: +1 :)
Здравствуйте, sidorov18, Вы писали:
S>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Несовместимость с ASCII, непереносимость, проблема 0-го байта, больший расход памяти (и времени) в большинстве случаев…

S>Если вы работаете с COM(который нужно, что бы из скриптов вызывался), к примеру, — UTF-8 будет таким же несовместимым. Здесь вопрос в окружении.


Нет, не работаю. Но множество библиотек, от XML-парсеров до GUI работают как раз с UTF-8. Не говоря уж о вводе/выводе (в том числе сетевом).

S>Но конвертирование, в большинстве случаев, проходит очень быстро, только если вопрос не упирается в мегабайт(ы) строк.


Т.е. нет проблем конвертировать каждый раз для COM?

S>Расход памяти тоже в большинстве случаев незаметен.


Это аргумент в основном для англоязычных. Очень много было криков из-за того, что Python3 требует в 2-4 раза больше памяти при работе с текстом, чем Python2 на тех же задачах. Хуже, что и скорость соответственно падала (а как вы думаете, вдвое больше байт перемолотить). Идентификаторы, ключевые слова, числа в десятичной записи, имена файлов, URL-ы — как правило помещаются в ASCII, поэтому это касается не только англоязычных.

S>И что за проблема 0-го байта?


Функции, ожидающие ASCIIZ, споткнутся на первом же байте со значением 0. В UTF-16 это скорее всего будет в одном из первых символов.

MOP>>А вот чем UTF-16 лучше UTF-8? Ничем. Сохраняет недостатки UTF-8 и добавляет свои.

S>в соседней ветке уточняем по поводу доступа по индексу.

Доступ по индексу — довольно редкая операция (может чуть чаще, чем языкозависимое сравнение строк без учёта регистра). И если нужно — можно и ICU подключить (впрочем, именно для этого есть и полегче библиотеки).

S>Но проблема совместимости так же актуальна и для UTF-8. Здесь вопрос окружения, а не ситуация, если бы

S>везде был UTF-8.

Это Microsoft создала эту проблему и практически единственная причина для работы с UTF-16 — её обход.
Re[4]: C++ и UTF8
От: Кодт Россия  
Дата: 27.10.11 13:35
Оценка: 1 (1) +2
Здравствуйте, okman, Вы писали:

O>Я думаю, что Вы лукавите.

O>Когда мы вызываем string.length, мы хотим длину строки в символах, а не каких-то char-like объектов.

Извините, что влезаю, но вот в этом месте есть то самое обещанное лукавство. Кто эти "мы"?
В некоторых случаях от строки требуется длина в символах, в других случаях — длина в codepoint-ах, в третьих — длина в байтах.

Разбивка строки на символы — задача, относящаяся к пользовательскому интерфейсу (начиная с того, куда каретку рисовать) или к весьма специфичной обработке текста.
В остальных случаях, включая даже неспецифический пользовательский интерфейс (ввод-вывод строки целиком, средствами операционной системы или готовых библиотек) хватает тупой трактовки: строка — массив char'ов или wchar'ов (и пересчитать wchar'ы в байты можно простым умножением на sizeof(wchar_t)).
Ну и спрашивается, зачем тратить время и память на создание и поддержание структуры данных, которая, вероятнее всего, не понадобится?

Более того, работа со строкой целиком может внутри скрывать разбор строки на буквы. Но это забота библиотеки, а не пользователя. Указываешь, скажем, текущую локаль de_DE.utf8, и пусть strcoll там эсцеты с умляутами сравнивает по всем правилам.
Перекуём баги на фичи!
Re[4]: C++ и UTF8
От: gegMOPO4  
Дата: 27.10.11 13:36
Оценка: +1
Здравствуйте, okman, Вы писали:
O>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Ну и что? Поскольку UTF-8 совместима с ASCII и обладает ещё рядом замечательных свойств, ничто не мешает использовать std::string как контейнер. А наличие ряда специализированных функций для работы со строками делает его предпочтительнее std::vector<char>.

O>Зачем писать (отлаживать, тестировать) специализации, когда есть готовые библиотеки ?

O>Вот чего я не понимаю.

Вы не поняли из-за чего uzhas так резко прекратил разговор. И-за того, что вы с ним (и мной) говорите о совершенно разных вещах.

Не нужно ничего отлаживать и тестировать, просто использовать.

MOP>>Какой результат вам нужен? Результат std::string::length — A count of the number of char-like objects (т.е. char в данном случае) currently in the string. Иными словами — количество байт в представлении UTF-8.

O>Я думаю, что Вы лукавите.
O>Когда мы вызываем string.length, мы хотим длину строки в символах, а не каких-то char-like объектов.

Так ли часто нужно именно количество символов? А суррогатные пары считаются? А комбинированные символы? А непечатные? А символы двойной ширины?

Размер в байтах имеет смысл чаще. Для остального всё равно нужно использовать специальные функции (например, определение длины строки в пикселях определённым шрифтом).

MOP>>Да практически все будут работать. Какие не? Нужно только помнить, что std::string::length возвращает не количество символов, а pos — смещение, а не номер символа.

O>Как на счет строковых итераторов и алгоритмов, работающих со строками ?

Нормально будут работать (большинство).

O>Что передавать аргументом string::find_first_of ?


Если символы в ASCII (не менее 99% случаев) — char, char const * или std::string. В остальных маргинальных случаях наверняка find_first_of будет плохим выбором, лучше регэкспы или ручная итерация с проверкой классов символов. От UTF-16 лучше не станет.
Re[8]: C++ и UTF8
От: gegMOPO4  
Дата: 27.10.11 13:44
Оценка:
Здравствуйте, okman, Вы писали:
O>Здравствуйте, gegMOPO4, Вы писали:
MOP>>В UTF-8 128 символа (в число которых входят наиболее частые) кодируются одним байтом.
O>Китайцы с Вами бы не согласились (см. выделенное).

Даже китайцы пишут программы на языках с английскими ключевыми словами, использую форматы и протоколы, в которых теги, имена параметров и разделители в ASCII. Да и числа наверняка записывают в десятичной системе «арабскими» цифрами.
Re[4]: C++ и UTF8
От: Pavel Dvorkin Россия  
Дата: 27.10.11 14:59
Оценка:
Здравствуйте, dilmah, Вы писали:


PD>>Как насчет strstr ?


D>и что же с strstr?



D>Первый байт любого символа всегда отличается от непервого байта.


А первый байт двухбайтового UTF-8 символа в строке, где ищем, не может совпасть с единственным байтом однобайтного символа в строке , которую ищем ?
With best regards
Pavel Dvorkin
Re[5]: C++ и UTF8
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.10.11 15:13
Оценка: 1 (1)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, dilmah, Вы писали:



D>>и что же с strstr?



D>>Первый байт любого символа всегда отличается от непервого байта.


PD>А первый байт двухбайтового UTF-8 символа в строке, где ищем, не может совпасть с единственным байтом однобайтного символа в строке , которую ищем ?


В том случае если строка, которую ищем, в отличной кодировке от UTF-8. Только зачем такие приключения?
Re[4]: Это всё условности...
От: Erop Россия  
Дата: 27.10.11 15:16
Оценка:
Здравствуйте, okman, Вы писали:

O>Я думаю, что Вы лукавите.

O>Когда мы вызываем string.length, мы хотим длину строки в символах, а не каких-то char-like объектов.

Смотря зачем она нам понадобилась...
В конце концов в юникоде есть такие коды, которые не являются самостоятельным символом, а можифицируют соседний. Например, приписывают к нему диакритический знак. Тебе в длине, которая тебе нужна, надо такие символы модификаторы считать за отдельный символ или нет? А ведь ещё эссет всякие есть. Её за скока буковок считать будем?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: C++ и UTF8
От: Erop Россия  
Дата: 27.10.11 15:18
Оценка:
Здравствуйте, okman, Вы писали:

O>Что передавать аргументом string::find_first_of ?


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

Главное, чего мне не понятно, а что ты хотел бы написать в этом месте ВМЕСТО string::find_first_of "если бы всё было по уму"?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: C++ и UTF8
От: Erop Россия  
Дата: 27.10.11 15:22
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А первый байт двухбайтового UTF-8 символа в строке, где ищем, не может совпасть с единственным байтом однобайтного символа в строке , которую ищем ?


Не может. Там прикольно всё сделано. Все байты уникальные типа.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: C++ и UTF8
От: dilmah США  
Дата: 27.10.11 15:24
Оценка: 6 (2) +2
D>>Первый байт любого символа всегда отличается от непервого байта.

PD>А первый байт двухбайтового UTF-8 символа в строке, где ищем, не может совпасть с единственным байтом однобайтного символа в строке , которую ищем ?


нет, это следует из второго свойства utf-8 которые ты почему-то отрезал от цитаты:

Кроме того если кол-во байтов в символах отличается то их первый байт тоже отличается.


первый байт однозначно определяет длину всей последующей цепочки.
Re[6]: C++ и UTF8
От: Erop Россия  
Дата: 27.10.11 15:36
Оценка:
Здравствуйте, dilmah, Вы писали:

D>первый байт однозначно определяет длину всей последующей цепочки.


Кроме того, непервый байт всегда отличается от первого вроде как...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Это всё условности...
От: okman Беларусь https://searchinform.ru/
Дата: 27.10.11 16:13
Оценка:
Здравствуйте, Erop, Вы писали:

E>Главное, чего мне не понятно, а что ты хотел бы написать в этом месте ВМЕСТО string::find_first_of "если бы всё было по уму"?


Любой символ юникода. Раз уж речь идет о UTF-8.
Но для этого нужна будет специализация find_first_of.

O>>Когда мы вызываем string.length, мы хотим длину строки в символах, а не каких-то char-like объектов.


E>Смотря зачем она нам понадобилась...

E>В конце концов в юникоде есть такие коды, которые не являются самостоятельным символом, а можифицируют соседний. Например, приписывают к нему диакритический знак. Тебе в длине, которая тебе нужна, надо такие символы модификаторы считать за отдельный символ или нет? А ведь ещё эссет всякие есть. Её за скока буковок считать будем?

Выполним std::normalize (гипотетический) и забудем.
Re[5]: C++ и UTF8
От: okman Беларусь https://searchinform.ru/
Дата: 27.10.11 16:13
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Вы не поняли из-за чего uzhas так резко прекратил разговор. И-за того, что вы с ним (и мной) говорите о совершенно разных вещах.


MOP>Не нужно ничего отлаживать и тестировать, просто использовать.


Использовать как раз не получится.
Стандартом обеспечивается только одна локализация.
Это значит, что уже только сравнение строк в UTF-8 без учета регистра запросто обломается.
Как и всякие toupper/tolower.

Алгоритмы, рассчитанные на правило "1 char == 1 byte" тоже подлежат редизайну.
То есть, какой-нибудь string tokenizer с такой строкой нормально работать не будет.
Не говорите, что это редкие задачи — лично я сталкиваюсь с ними постоянно.

MOP>Так ли часто нужно именно количество символов? А суррогатные пары считаются? А комбинированные символы? А непечатные? А символы двойной ширины?


Вот поэтому я использую ICU, где символы хранятся в едином внутреннем представлении — UTF-32.

O>>Как на счет строковых итераторов и алгоритмов, работающих со строками ?


MOP>Нормально будут работать (большинство).


Про find_first_of я уже спрашивал.
Где метод std::string, который вернул бы мне количество символов ?
Будет ли смысл в операторе индексации (и string.at() ) ?
Кстати, интересно было бы посмотреть на random_shuffle или reverse_iterator для такой строки.
Ах да, я все забываю — это же не строка, а набор байт.
Зачем все эти извращения, если есть специальные инструментальные средства и библиотеки,
избавляющие от необходимости "жонглирования" понятиями char/byte в уме ?
Re[5]: C++ и UTF8
От: okman Беларусь https://searchinform.ru/
Дата: 27.10.11 16:13
Оценка: 1 (1)
Здравствуйте, Кодт, Вы писали:

К>Разбивка строки на символы — задача, относящаяся к пользовательскому интерфейсу (начиная с того, куда каретку рисовать) или к весьма специфичной обработке текста.

К>В остальных случаях, включая даже неспецифический пользовательский интерфейс (ввод-вывод строки целиком, средствами операционной системы или готовых библиотек) хватает тупой трактовки: строка — массив char'ов или wchar'ов (и пересчитать wchar'ы в байты можно простым умножением на sizeof(wchar_t)).
К>Ну и спрашивается, зачем тратить время и память на создание и поддержание структуры данных, которая, вероятнее всего, не понадобится?

Вот практический пример.
Задача — написать библиотеку, которая фильтрует веб-контент и вырезает из него запрещенные слова.
Контент идет на разных языках и в разных кодировках (чаще всего — в UTF-8).
Вот и как тут пользоваться std::string, если она BOM не понимает, нормализацию делать не умеет, и
даже не может преобразовать найденное слово к нижнему/верхнему регистру ?

К>Более того, работа со строкой целиком может внутри скрывать разбор строки на буквы. Но это забота библиотеки, а не пользователя. Указываешь, скажем, текущую локаль de_DE.utf8, и пусть strcoll там эсцеты с умляутами сравнивает по всем правилам.


Visual C++ выбрасывает исключение, если создать локаль с именем "ru_RU.utf8" (другие варианты тоже пробовались).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.