Здравствуйте, okman, Вы писали:
O>Это потому, что надо уметь признавать свои ошибки. O>Как это делаю я.
Нету тут ошибок. Все зависит от задачи. Вот, например, библиотека, которая устраняет недостатки std::string c utf-8. Самый простой и экономичный вариант, ибо используется только когда надо.
Здравствуйте, okman, Вы писали:
O>Любой символ юникода. Раз уж речь идет о UTF-8. O>Но для этого нужна будет специализация find_first_of.
Чем оно будет отличаться от поиска подстроки?
O>Выполним std::normalize (гипотетический) и забудем.
Э-э-э, зачем? Тем более, что в каком-нибудь тайском этот твой std::normalize будет весьма гипотетическим.
А ещё есть кроейский, например. Там можно буквы блока (слога) писать, как последовательные юникоды, а можно, как один. И чего?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, okman, Вы писали:
O>Использовать как раз не получится. O>Стандартом обеспечивается только одна локализация. O>Это значит, что уже только сравнение строк в UTF-8 без учета регистра запросто обломается. O>Как и всякие toupper/tolower.
Это ещё почему? Нипишт правильный локейл и всё будет...
Только, если честно, я бы не сильно напрягался бы из-за toupper и tolower в случае UTF-16, например...
O>Алгоритмы, рассчитанные на правило "1 char == 1 byte" тоже подлежат редизайну. O>То есть, какой-нибудь string tokenizer с такой строкой нормально работать не будет. O>Не говорите, что это редкие задачи — лично я сталкиваюсь с ними постоянно.
Да ну? Всякие пробелмы с запятыми -- они однобайтовые, а в UTF-16 -- двубайтовые. А всякие произвольные цепочки символов, так там пофиг сколько в них символов и сколько байтов/двубайтов.
В этом смысле UTF-16 предпочтительнее тем, что на доп. плоскостях лежат такие символы, которые почти всегда можно считать строками, без ограничения общности...
O>Вот поэтому я использую ICU, где символы хранятся в едином внутреннем представлении — UTF-32.
Да используй, ради Бога, если тебе это нужно/удобно и всё такое. Но это ни разу не единственное верное решение...
O>Где метод std::string, который вернул бы мне количество символов ? O>Будет ли смысл в операторе индексации (и string.at() ) ? O>Кстати, интересно было бы посмотреть на random_shuffle или reverse_iterator для такой строки. O>Ах да, я все забываю — это же не строка, а набор байт.
Ну юникод вообще так спроектирован, что одному глифу в выводящемся на устройство печати тексте, соответствует цепочка кодов, в общем случае. В чём принципиальная разница, цепочка юникодов или цепочка байт или двубайтов?
O>Зачем все эти извращения, если есть специальные инструментальные средства и библиотеки, O>избавляющие от необходимости "жонглирования" понятиями char/byte в уме ?
А не надо никакого жонглирования. В MB-подходе буква -- это ЦЕПОЧКА кодов. И всё. Нужен итератор по буквам -- пиши итератор по буквам поверх итератора по кодам. Только не совсем понятно, что он будет выдавать по operator *(), а так всё прямо...
Но если у тебя какие-то конкретные задачи такие, что тебе надо вот с китайским прямо вот работать-работать и именно с текстами, и как-то небанально их обрабатывать, то тебя скорее всего всё равно не устроят stl-ные строки...
Так что всё равно чего-то тут винтить надо будет. А вот если у тебя речь о именах файлов, например и именах пользователей, то тебе пофиг на то, UTF-16 там, UTF-8 или UTF-32... Да, кстати, я на работе как раз вот с иероглификой всякой и работаю, так что с проблемой знаком непосредственно
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, okman, Вы писали:
O>Вот практический пример. O>Задача — написать библиотеку, которая фильтрует веб-контент и вырезает из него запрещенные слова. O>Контент идет на разных языках и в разных кодировках (чаще всего — в UTF-8). O>Вот и как тут пользоваться std::string, если она BOM не понимает, нормализацию делать не умеет, и O>даже не может преобразовать найденное слово к нижнему/верхнему регистру ?
Ой, тоже мне проблема.
Я бы работал как раз в UTF-16, а не UTF-8. Имел бы правило нормализации, которео символы с доп. плоскостей оставляет на месте + словарь или коллекцию словарей запретов. Был бы на этом пути небольшой гемор с турецкими i-I и ещё двумя "и", но я бы его решал по мере поступления примеров плохих турецких слов с такими буквами...
В конце концов, можно иметь два словаря -- один чувстивтельный к регистру, а другой нет. И те слова, в которых проблемы с турецкой буквой заности в чувствительный...
Собственно всё.
Что скажут любители UTF-8 и stl?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, okman, Вы писали: O>Это значит, что уже только сравнение строк в UTF-8 без учета регистра запросто обломается. O>Как и всякие toupper/tolower.
В 90% задач toupper/tolower не нужны. В 90% оставшихся достаточно toupper/tolower только с ASCII. Оставшийся 1% — где действительно нужно, и UTF-16 или UTF-32 сами по себе не помогут, нужно использовать ICU (но в 90% его не используют и работают с регистром неправильно ).
O>Алгоритмы, рассчитанные на правило "1 char == 1 byte" тоже подлежат редизайну. O>То есть, какой-нибудь string tokenizer с такой строкой нормально работать не будет. O>Не говорите, что это редкие задачи — лично я сталкиваюсь с ними постоянно.
Подавляющее большинство токенайзеров (использующих разделители из ASCII) будут работать правильно. Главное — будут работать старые токенайзеры, авторы которых и не слышали о UTF-8. А что с ними будет на UTF-16 или UTF-32? Пшшш…
MOP>>Так ли часто нужно именно количество символов? А суррогатные пары считаются? А комбинированные символы? А непечатные? А символы двойной ширины? O>Вот поэтому я использую ICU, где символы хранятся в едином внутреннем представлении — UTF-32.
Это не отвечает на все вопросы. Потому, что ответы зависят от предметной области.
O>>>Как на счет строковых итераторов и алгоритмов, работающих со строками ? MOP>>Нормально будут работать (большинство). O>Про find_first_of я уже спрашивал.
И я ответил.
O>Где метод std::string, который вернул бы мне количество символов ?
Вы так и не ответили, зачем вам количество символов. Я знаю один ответ, довольно специфичное применение.
O>Будет ли смысл в операторе индексации (и string.at() ) ?
Смотря что мы будем делать с результатом.
O>Кстати, интересно было бы посмотреть на random_shuffle или reverse_iterator для такой строки.
Зачем? Это очень специфичные задачи, где могло бы понадобиться.
O>Зачем все эти извращения, если есть специальные инструментальные средства и библиотеки, O>избавляющие от необходимости "жонглирования" понятиями char/byte в уме ?
Затем, что в подавляющем числе случаев «жонглировать» не нужно, равно как и применять специальные средства (а где нужно — набор средств будет разным). И зачем тогда постоянная перекодировка из внутреннего представления в UTF-8, с которым работает большинство библиотек?
Здравствуйте, gegMOPO4, Вы писали:
MOP>И зачем тогда постоянная перекодировка из внутреннего представления в UTF-8, с которым работает большинство библиотек?
Всё-таки с какой кодировкой работает большинство библиотек очень зависит от окружения, библиотек, задач и т. д...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Но ответ по сути (насчет возможности использовать str*) это не меняет.
strlen вернет не поймешь что, вернее , поймешь, но толку от этого никакого нет.
strlwr и strupr не будут работать
stricmp тоже
strrev такого натворит, что никто потом не разберется.
strchr тоже работать не будет, хотя и принимает int.
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>И зачем тогда постоянная перекодировка из внутреннего представления в UTF-8, с которым работает большинство библиотек? E>Всё-таки с какой кодировкой работает большинство библиотек очень зависит от окружения, библиотек, задач и т. д...
Зависит. Но большинство софта пишут люди из ASCII- или Latin1-мира (хорошо, большинство сто́ящего софта, Китай не считаем), поэтому текстовые интерфейсы прежде всего с char *. А потом, если руки дойдут… (а часто и так хорошо). И в инете как-то UTF-16 не густо.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Зависит. Но большинство софта пишут люди из ASCII- или Latin1-мира (хорошо, большинство сто́ящего софта, Китай не считаем), поэтому текстовые интерфейсы прежде всего с char *.
А теперь внимательно вынимаем голову из мира лялиха и смотрим в сторону винды...
Ничего не виднеется такого UTF-16-образного?
MOP>А потом, если руки дойдут… (а часто и так хорошо). И в инете как-то UTF-16 не густо.
Ну так нет-то, это только одно из окружений...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>Зависит. Но большинство софта пишут люди из ASCII- или Latin1-мира (хорошо, большинство сто́ящего софта, Китай не считаем), поэтому текстовые интерфейсы прежде всего с char *. E>А теперь внимательно вынимаем голову из мира лялиха и смотрим в сторону винды... E>Ничего не виднеется такого UTF-16-образного?
Это только одно из окружений...
Ну вот угораздило МС сделать такую ошибку, теперь всем расплачиваться.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>strlen вернет не поймешь что, вернее , поймешь, но толку от этого никакого нет. PD>strlwr и strupr не будут работать PD>stricmp тоже PD>strrev такого натворит, что никто потом не разберется. PD>strchr тоже работать не будет, хотя и принимает int.
Беда тут в том, что и UTF-32 ничего не решает...
Увы и ах, для всяких "простых" символов, используемых для форматирования, ну там пробелов, табуляторов, всяких скобок и тире UTF-16 вообще полностью подходит, как однословная колдировка, а во многих случаях и UTF-8 подойдёт.
Для многих случаев, когда нужен ещё и регистр, UTF-16 полностью канает, так как все символы, для которых регистр релевантен лежат на главной плоскости.
А для всяких там реверсов и прочих поисков байта/широкго символа всё равно юникод не годиться.
Там всё равно в общем случае символу на печати соответствует цепочка символов в тексте, правда, насколько я понимаю, могут быть и обратные расклады, когда в тексте один код, а на печати какая-нибудь лигатура ttf или TM или ...
В общем, хочешь юникода -- забудь о взаимно однозначном отображении сивола на печати в код и обратно. Отображение нетривильное. И писать код надо с учётом особенностей этого отображения.
В этом смысле отображение в UTF-8 или в UTF-16 или в UTF-32 ничем принципиально не отличается...
Единственное существенное отличие -- множества пунктуаторов, кторые помещаются в один код. В UTF-8 это только европейскеи пунктуаторы, и то. не совсем все, а в UTF-16 уже все-любые. И с работой с регистром знаков отличие.
Если в UTF-8 это гемор, то во UTF-32 и в UTF-16 всё просто прямо и одинаково выходит...
При этом с регисторм есть такая беда, что всё равно надо знать язык, чтобы понять какие маленькие буквы каким большим соответствуют. Так что папа что там, что сям. Короче наивного простого и точного решения нет. Есть либо точное, но тогда всё надо делать не так, как в мире char*, и тогда пофиг какая кодировка, либо приблизительное, но тогда тоже пофиг какая кодировка
В общем я не понимаю в чём принципиальное отличие-то?
IMHO, только окружение и влияет... Ну и немножко замуты с регистром ещё, могут UTF-8 отсечь...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, gegMOPO4, Вы писали:
MOP>Здравствуйте, Erop, Вы писали: E>>Ничего не виднеется такого UTF-16-образного?
MOP>Это только одно из окружений...
Дык я про то и говорю, что удобная кодировка, в первую очередь, определяется окружением и задачами, а не какими-то принципиальными преимуществами кодировок.
У UTF-16 и UTF-32 есть небольшое преимущество, состоящее в том, что проще работать с решистрами букв. Но оно редко бывает значимым, тем не менее...
MOP>Ну вот угораздило МС сделать такую ошибку, теперь всем расплачиваться.
Я не считаю, что это прямо вот ошибка-ошибка. Кодировки-то равноправны на самом деле.
В мире лялиха было одобнее UTF-8, а в мире винды нет. Если начинать с читсого листа, то UTF-16 чуть лучше, из-за того, что регистры...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>Здравствуйте, Erop, Вы писали: E>>>Ничего не виднеется такого UTF-16-образного? MOP>>Это только одно из окружений... E>Дык я про то и говорю, что удобная кодировка, в первую очередь, определяется окружением и задачами, а не какими-то принципиальными преимуществами кодировок. E>У UTF-16 и UTF-32 есть небольшое преимущество, состоящее в том, что проще работать с решистрами букв. Но оно редко бывает значимым, тем не менее...
Ошибкой было бы думать, что с регистрами в UTF-16 и UTF-32 просто (русскому с регистром повезло (в отличие от немецкого), но сортировка нетривиальна). Вы-то знаете, но многие эту ошибку делают. Так что это кажущееся преимущество, пока жареный петух не клюнет.
MOP>>Ну вот угораздило МС сделать такую ошибку, теперь всем расплачиваться. E>Я не считаю, что это прямо вот ошибка-ошибка. Кодировки-то равноправны на самом деле.
Ошибка в том, что хотели перепрыгнуть пропасть, но чуть-чуть не допрыгнули. Как тут не вспомнить «640 Кб хватит всем»?
E>В мире лялиха было одобнее UTF-8, а в мире винды нет. Если начинать с читсого листа, то UTF-16 чуть лучше, из-за того, что регистры...
Если начинать с совсем чистого листа, следовало бы делать char 16-битным. Но Ритчи† уже далеко.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Ошибкой было бы думать, что с регистрами в UTF-16 и UTF-32 просто (русскому с регистром повезло (в отличие от немецкого), но сортировка нетривиальна). Вы-то знаете, но многие эту ошибку делают. Так что это кажущееся преимущество, пока жареный петух не клюнет.
Ну так я про то же. Что если всё по уму делать, то на кодировку или почти пофиг. Всё равно там не в кодировке дело.
А если не по уму, а приблизительно, то тоже пофиг или почти пофиг...
Но, бывают и задачи, в которых UTF-16 лучше. Например, надо тебе найти все начала больших букв в тексте...
MOP>Ошибка в том, что хотели перепрыгнуть пропасть, но чуть-чуть не допрыгнули. Как тут не вспомнить «640 Кб хватит всем»?
Ну так 640 и хватало долгое время. MS-DOS очень долго протянула...
А пропасть-то они перепрыгнули. Сначала все локализовались на 16 бит, а потом на UTF-2 перешли, кому надо.
Китай-то не всегда был так уж сильно компьютеризирован-то
Ну и вообще, что там кто и когда делал и в чём виноват или имеет заслуги в вопросе "какую кодировку выбрать для представления текстов в данной конркетной программе СЕЧАС" имеет крайне незначительное отношение...
MOP>Если начинать с совсем чистого листа, следовало бы делать char 16-битным. Но Ритчи† уже далеко.
Тоже не согласен.
char -- это совсем и не обязательно только буквы...
Я ещё раз *намекаю* между разными UTF принципиальных отличий нет. Есть мелкие тактические преимущества, завиящие от задач и окружения и только...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>Ошибкой было бы думать, что с регистрами в UTF-16 и UTF-32 просто (русскому с регистром повезло (в отличие от немецкого), но сортировка нетривиальна). Вы-то знаете, но многие эту ошибку делают. Так что это кажущееся преимущество, пока жареный петух не клюнет. E>Ну так я про то же. Что если всё по уму делать, то на кодировку или почти пофиг. Всё равно там не в кодировке дело. E>А если не по уму, а приблизительно, то тоже пофиг или почти пофиг...
Всё так. Но у каждого свой пофиг и нафиг. С одной стороны — 40-летняя традиция Си и какая-никакая совместимость с ASCII-only софтом, с другой — новый API Windows. Р-р-разорвись, раз-два.
E>Но, бывают и задачи, в которых UTF-16 лучше. Например, надо тебе найти все начала больших букв в тексте...
Это не та задача. Тут лучше 8-битовая кодировка (таблица на 256 против 65536 ), а если не хватит — регэксп.
Та задача — обильно взаимодействовать с WinAPI или некоторыми виндовыми форматами данных (и не взаимодействовать с другим API). Вынужденно, но мир несовершенен.
MOP>>Ошибка в том, что хотели перепрыгнуть пропасть, но чуть-чуть не допрыгнули. Как тут не вспомнить «640 Кб хватит всем»? E>Ну так 640 и хватало долгое время. MS-DOS очень долго протянула...
А груз совместимости ещё дольше тянули. С уникодом решили гордиев узел рубить, но отрубили слишком коротко.
E>А пропасть-то они перепрыгнули. Сначала все локализовались на 16 бит, а потом на UTF-2 перешли, кому надо. E>Китай-то не всегда был так уж сильно компьютеризирован-то
Китайцам сейчас так же плохо, как нам в мире 7-битного ASCII, где даже букву «р» в Norton Commander не ввести.
А как там в Windows8 API? Не собираются сделать ещё одно семейство функций, для UTF-32?
E>Ну и вообще, что там кто и когда делал и в чём виноват или имеет заслуги в вопросе "какую кодировку выбрать для представления текстов в данной конркетной программе СЕЧАС" имеет крайне незначительное отношение...
Такое же, как ширина лошадиной задницы…
MOP>>Если начинать с совсем чистого листа, следовало бы делать char 16-битным. Но Ритчи† уже далеко.
E>Тоже не согласен. E>char -- это совсем и не обязательно только буквы...
А для не-букв Ритчи следовало сделать byte. PDP-11 так заточен был на 16-битные слова…
E>Я ещё раз *намекаю* между разными UTF принципиальных отличий нет. Есть мелкие тактические преимущества, завиящие от задач и окружения и только...
Здравствуйте, gegMOPO4, Вы писали:
MOP>Всё так. Но у каждого свой пофиг и нафиг. С одной стороны — 40-летняя традиция Си и какая-никакая совместимость с ASCII-only софтом, с другой — новый API Windows. Р-р-разорвись, раз-два.
Не понимаю. Чего именно тебе под винду не хватает?
MOP>Это не та задача. Тут лучше 8-битовая кодировка (таблица на 256 против 65536 ), а если не хватит — регэксп.
Полная фигня. Уже вся латиница + вся кириллица не поместятся в такую таблицу.
Кроме того, мы же обсуждаем UTF-8 vs UTF-16 vs UTF-32, а так, под каждую задачу можно напридумывать кодировок, какие проблемы?
MOP>Китайцам сейчас так же плохо, как нам в мире 7-битного ASCII, где даже букву «р» в Norton Commander не ввести.
Что-то я не заметил, что им плохо...
Кроме того, на доп. плосткостях UTF-16 всякая маргинальщина сидит вообще-то. Из хоть как-то употребимого могу только контонский диалект вспомнить. Ну да сколько того Гон-Конгу-то?
MOP>А как там в Windows8 API? Не собираются сделать ещё одно семейство функций, для UTF-32?
Не знаю. Я к MS отношения имею мало.
Но я не понимаю, зачем оно надо-то?
Я ещё раз говорю, что все три UTF примерно одинаково удобны или неудобны...
MOP>Такое же, как ширина лошадиной задницы…
Ну это всё мифы, басни, предрассудки. Короче достойный богаж знаний...
MOP>А для не-букв Ритчи следовало сделать byte. PDP-11 так заточен был на 16-битные слова…
И что с того? PDP-11 уже давно того, а 8-битный байт живее всех живых. И Ричи и С тут не при чём вообще.
MOP>В этом и есть отличия.
Ну отличия в задачах и окружениии есть всегда. В этом и состоит работа хорошего инженера, чтобы всё учесть и сделать правильный выбор...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, whitewin, Вы писали:
D>>с чего вдруг?
W>strcat(), strcpy() будут работать, а вот в strcmp() побайтовое сравнение может дать неверный результат
Смотря что вы вкладываете в понятие "верный результат".
Оно, конечно, не подходит для сортировки по национальному алфавиту, отличному от латинского, но если сравнение строк нужно, к примеру, с целью поиска, то вполне себе strcmp() работает корректно.
Re[6]: плоски текст не так прост, как кажется на первый взгл
Pzz>Оно, конечно, не подходит для сортировки по национальному алфавиту, отличному от латинского, но если сравнение строк нужно, к примеру, с целью поиска, то вполне себе strcmp() работает корректно.
Ну, в каком-то смысле я, конечно, соглашусь, но не могу не заметить, что и сравнение с целью поиска задачка тоже непостая, к сожалению.
Бывает поиск чувствительный и нечувствительный к регистру, форме букв (начальная там, кончная и т. д.), наличию диакритических знаков, различным способам записи оного и того же символа и так далее...
При этом сё это ещё и от локейла может зависеть...
Так что даже если абстрагироваться от того, что бывает ещё и разное направления письма + знаки смены направления строки и прочая непечатная и управляющая гадость, то станет ясно, что юникодный комитет смог из простого плоского текста сделат мегаребус для разработчкиа
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>При этом с регисторм есть такая беда, что всё равно надо знать язык, чтобы понять какие маленькие буквы каким большим соответствуют.
LCMapString
For a locale specified by identifier, maps one input character string to another using a specified transformation, or generates a sort key for the input string.
int LCMapString(
LCID Locale,
DWORD dwMapFlags, LPCTSTR lpSrcStr,
int cchSrc,
LPTSTR lpDestStr,
int cchDest
);
LCMAP_LOWERCASE For locales and scripts capable of handling uppercase and lowercase, map all characters to lowercase.
LCMAP_UPPERCASE For locales and scripts capable of handling uppercase and lowercase, map all characters to uppercase