Здравствуйте, Аноним, Вы писали:
А>Подскажите пожалуйста, как в С++ работать со строками в кодировке UTF-8 ? А>(требуется стандартный набор строковых функций — strcmp(), strcat(), strcpy()... )
Вижу, тут у вас плюсы-минусы раздают, дай-ка я себе что-нибудь отгребу...
Нельзя использовать строки std:(w)string для работы с UTF-8.
Потому что шаблонный тип для basic_string — это char и wchar_t, длина которого фиксирована.
В Visual C++ это 1 и 2 байта соответственно. А UTF-8 — многобайтовая кодировка, символ в ней
может быть представлен как одним байтом, так и четырьмя.
Поэтому ни std::string::length, ни использование строковых итераторов и алгоритмов,
не будет давать нужный результат. Кто не верит, может попробовать считать из файла в UTF-8
какую-нибудь строчку в кириллице, а потом средствами std:(w)string попробовать поработать с ней.
Какое-то подмножество строковых функций будет работать, остальные — нет.
Правильный подход тут уже указали — нужно подключать сторонние библиотеки вроде ICU и
использовать те строковые типы, которые они предлагают.
А>>(требуется стандартный набор строковых функций — strcmp(), strcat(), strcpy()... )
D>strcat, strcpy работают без изменений
D>В дополнение к strcmp есть strcoll, но strcmp тоже работает
strcmp(), strcat(), strcpy() будут работать некорректно
D>>Первый байт любого символа всегда отличается от непервого байта.
PD>А первый байт двухбайтового UTF-8 символа в строке, где ищем, не может совпасть с единственным байтом однобайтного символа в строке , которую ищем ?
нет, это следует из второго свойства utf-8 которые ты почему-то отрезал от цитаты:
Кроме того если кол-во байтов в символах отличается то их первый байт тоже отличается.
первый байт однозначно определяет длину всей последующей цепочки.
Здравствуйте, Banned by IT, Вы писали:
WM>>Весьма сомнительное достижение. BBI>Я бы назвал это разумным компромиссом.
Шутишь?
Разумный компромисс — это когда берут два способа и объединяют их достоинства вопреки мелким недостаткам.
А вот когда берут два способа, объединяют их недостатки ради мелких достоинств — это ну никак не называется компромиссом.
Тут как раз больше недостатков: увеличили объём по сравнению с UTF-8, замедлили скорость поиска по сравнению с UTF-32.
Нет, UTF-16 появился не в результате компромисса. Достоинство UTF-16 в частичной совместимости с UCS-2, а именно корректная строка в UCS-2 остаётся корректной в UTF-16 (кстати говоря, точно такая же ситуация и у пары ASCII–UTF-8). То есть использование UTF-16 позволяло относительно с низкими затратами перевести на современный юникод программы рассчитанные на UCS-2 (точно так же как UTF-8 был призван относительно с низкими затратами перевести на современный юникод программы рассчитанные на ASCII). Вот только UCS-2 уже умер (в отличии от ASCII), а вместе с ним исчезло и последнее достоинство UTF-16. Всё просто — это представление, созданное ради обратной совместимости, сейчас существует ради обратной совместимости.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Здравствуйте, okman, Вы писали: O>>Это значит, что уже только сравнение строк в UTF-8 без учета регистра запросто обломается. O>>Как и всякие toupper/tolower.
MOP>В 90% задач toupper/tolower не нужны. В 90% оставшихся достаточно toupper/tolower только с ASCII. Оставшийся 1% — где действительно нужно, и UTF-16 или UTF-32 сами по себе не помогут, нужно использовать ICU (но в 90% его не используют и работают с регистром неправильно ).
Похоже на то, что спорят тут негры с финами — нужна куртка зимняя или нет.
фины говорят, что нужна, а то замерзнешь. А негры говорят — холод — это очень специфическая температура, встречающаяся раз в 100 лет. И для нее сойдет и 3 свитера, нахрен куртка.
Что касается UTF-16 — в каких языках она не покрывает символ/2 байта?
W>>strcmp(), strcat(), strcpy() будут работать некорректно
D>с strcmp действительно будут не очень хорошие вещи если нужно чтобы эквивалентные коды считались равными, но работать то все равно будет
Здравствуйте, sidorov18, Вы писали: S>Здравствуйте, Аноним, Вы писали: А>>Подскажите пожалуйста, как в С++ работать со строками в кодировке UTF-8 ? А>>(требуется стандартный набор строковых функций — strcmp(), strcat(), strcpy()... ) S>А что именно хочется делать со строками? S>Может сразу в UTF-16 переводить?
Здравствуйте, sidorov18, Вы писали: S>Здравствуйте, gegMOPO4, Вы писали: MOP>>Здравствуйте, sidorov18, Вы писали: S>>>Может сразу в UTF-16 переводить? MOP>>UTF-16 во всех смыслах хуже UTF-8. S> S>Скажите хоть пару.
Несовместимость с ASCII, непереносимость, проблема 0-го байта, больший расход памяти (и времени) в большинстве случаев…
А вот чем UTF-16 лучше UTF-8? Ничем. Сохраняет недостатки UTF-8 и добавляет свои.
Здравствуйте, okman, Вы писали:
O>Я думаю, что Вы лукавите. O>Когда мы вызываем string.length, мы хотим длину строки в символах, а не каких-то char-like объектов.
Извините, что влезаю, но вот в этом месте есть то самое обещанное лукавство. Кто эти "мы"?
В некоторых случаях от строки требуется длина в символах, в других случаях — длина в codepoint-ах, в третьих — длина в байтах.
Разбивка строки на символы — задача, относящаяся к пользовательскому интерфейсу (начиная с того, куда каретку рисовать) или к весьма специфичной обработке текста.
В остальных случаях, включая даже неспецифический пользовательский интерфейс (ввод-вывод строки целиком, средствами операционной системы или готовых библиотек) хватает тупой трактовки: строка — массив char'ов или wchar'ов (и пересчитать wchar'ы в байты можно простым умножением на sizeof(wchar_t)).
Ну и спрашивается, зачем тратить время и память на создание и поддержание структуры данных, которая, вероятнее всего, не понадобится?
Более того, работа со строкой целиком может внутри скрывать разбор строки на буквы. Но это забота библиотеки, а не пользователя. Указываешь, скажем, текущую локаль de_DE.utf8, и пусть strcoll там эсцеты с умляутами сравнивает по всем правилам.
Здравствуйте, 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, с которым работает большинство библиотек?
Здравствуйте, sidorov18, Вы писали:
S>+ если понадобится узнать количество символов в строке или доступ по индексу — моментально вылезут удобства UTF-16.
Это какие же? С UTF-16 при решении данных задач работать так же неудобно как и с UTF-8.
Вся разница лишь в том, что в UTF-8 один символ может занимать 1,2,3,4 байта, а в в UTF-16 соответственно 2 или 4 байта.
То есть если вам нужно посчитать число символов в строке, то всё равно придётся бегать и анализировать каждый байт в обоих этих представлениях.
Если вам нужно обращаться к символу по индексу, то так же придётся бежать с начала строки и анализировать байты (ну или двухбайтовые позиции, что в данном случае не важно), суммируя количество найденных символов, что делается так же как и в UTF-8.
Вообще, в юникоде были только два представления, которые позволяют адресовать символ непосредственно по его номеру: UTF-32 и UCS-2. Но второе представление — это артефакт оставшийся с первых версий юникода, и сейчас оно не поддерживается, и поэтому остаётся только UTF-32.
И уж если говорить об удобствах, то UTF-16 — это очень неудобный способ кодирования символов, который взял и объединил недостатки UTF-8 и UTF-32. От UTF-8 он взял переменную длинну кодирования символов (что не позволяет быстро адресовать символы по индексу), а от UTF-32 он взял избыточные требования к памяти. Весьма сомнительное достижение.
Здравствуйте, uzhas, Вы писали:
U>есть у меня опыт работы с "правильным" подходом U>так вот выбросили его через два года, ибо устали: тормоза в рантайме и депенд на ICU (как следствие тормоза компиляции, усложнение инсталяторов), а выигрыша ноль U>заменили на std::string (UTF8), std::wstring (win)\ std::basic_string<short> (linux) (UTF16) и стало замечательно
То есть, Вы предлагаете человеку, который хочет работать в C++ с UTF-8, не полагаться на
библиотеки вроде ICU или iconv, а написать специализацию basic_string для типа, достаточного по
размеру, чтобы вмещать любые символы UTF-8 (видимо, unsigned int) и пользоваться ей ?
И при этом ссылаетесь на опыт разработки серверного приложения, где такие "мелочи", как длина
строки, несущественны ? Не могу согласиться с такой точкой зрения.
Здравствуйте, okman, Вы писали: O>Нельзя использовать строки std:(w)string для работы с UTF-8. O>Потому что шаблонный тип для basic_string — это char и wchar_t, длина которого фиксирована. O>В Visual C++ это 1 и 2 байта соответственно. А UTF-8 — многобайтовая кодировка, символ в ней O>может быть представлен как одним байтом, так и четырьмя.
Ну и что? Поскольку UTF-8 совместима с ASCII и обладает ещё рядом замечательных свойств, ничто не мешает использовать std::string как контейнер. А наличие ряда специализированных функций для работы со строками делает его предпочтительнее std::vector<char>.
O>Поэтому ни std::string::length, ни использование строковых итераторов и алгоритмов, O>не будет давать нужный результат.
Какой результат вам нужен? Результат std::string::length — A count of the number of char-like objects (т.е. char в данном случае) currently in the string. Иными словами — количество байт в представлении UTF-8.
O> Кто не верит, может попробовать считать из файла в UTF-8 O>какую-нибудь строчку в кириллице, а потом средствами std:(w)string попробовать поработать с ней. O>Какое-то подмножество строковых функций будет работать, остальные — нет.
Да практически все будут работать. Какие не? Нужно только помнить, что std::string::length возвращает не количество символов, а pos — смещение, а не номер символа.
Фактически единственная операция, где std::string недостаточно — обрезка строки по заданному количеству символов.
O>Правильный подход тут уже указали — нужно подключать сторонние библиотеки вроде ICU и O>использовать те строковые типы, которые они предлагают.
Только тогда, когда вам действительно нужны возможности ICU. Во многих случаях можно обойтись без.
Здравствуйте, Erop, Вы писали:
O>>Какой ? К примеру, на Visual C++ любые конструкторы std::locale, инициализированные строками O>>вроде "ru_RU.utf-8", обламываются.
E>Ну ты же сам можешь его реализовать, если библа не поддреживает...
Не надо ничего реализовывать, всё украдено до нас. Просто в виндах национальные локали называются иначе, чем во всём мире. http://msdn.microsoft.com/en-us/library/hzz3tw78(v=VS.71).aspx
То есть, не ru_RU, а rus_rus или просто russian. А немецкий, соответственно, deu или german.
(Я тоже был немало удивлён, когда setlocale("ru_RU.1251") обломался в русской винде. Но не сдался, а полез читать этот rtfm.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Здравствуйте, sidorov18, Вы писали: S>>Здравствуйте, gegMOPO4, Вы писали: MOP>>>Здравствуйте, sidorov18, Вы писали: S>>>>Может сразу в UTF-16 переводить? MOP>>>UTF-16 во всех смыслах хуже UTF-8. S>> S>>Скажите хоть пару.
MOP>Несовместимость с ASCII, непереносимость, проблема 0-го байта, больший расход памяти (и времени) в большинстве случаев…
Если вы работаете с COM(который нужно, что бы из скриптов вызывался), к примеру, — UTF-8 будет таким же несовместимым. Здесь вопрос в окружении.
Но конвертирование, в большинстве случаев, проходит очень быстро, только если вопрос не упирается в мегабайт(ы) строк.
Расход памяти тоже в большинстве случаев незаметен.
И что за проблема 0-го байта?
MOP>А вот чем UTF-16 лучше UTF-8? Ничем. Сохраняет недостатки UTF-8 и добавляет свои.
в соседней ветке уточняем по поводу доступа по индексу.
Но проблема совместимости так же актуальна и для UTF-8. Здесь вопрос окружения, а не ситуация, если бы
везде был UTF-8.
Здравствуйте, 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 отсечь...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
D>>strcat, strcpy работают без изменений D>>В дополнение к strcmp есть strcoll, но strcmp тоже работает W>strcmp(), strcat(), strcpy() будут работать некорректно
Здравствуйте, 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 — её обход.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Т.е. нет проблем конвертировать каждый раз для COM?
Нет. но...
В моей практике — в винде я всегда использовал UTF-16. И с этим небыло проблем.
Конвертировать самому в UTF-8 — только для HTTP POST запросов. которые посылались не часто и не несли тонны текста.
Поскольку использовалось много COM-а — в противом случае нужно было бы много конвертировать.
Все таки маленький, но плюс — больше конвертировать или меньше конвертировать..
S>>Расход памяти тоже в большинстве случаев незаметен.
MOP>Это аргумент в основном для англоязычных. Очень много было криков из-за того, что Python3 требует в 2-4 раза больше памяти при работе с текстом, чем Python2 на тех же задачах. Хуже, что и скорость соответственно падала (а как вы думаете, вдвое больше байт перемолотить). Идентификаторы, ключевые слова, числа в десятичной записи, имена файлов, URL-ы — как правило помещаются в ASCII, поэтому это касается не только англоязычных.
Может..
На студия я не жалуюсь. Возможности проверить нет, конечно, но сомневаюсь, что они используют там внутри UTF-8.
S>>И что за проблема 0-го байта?
MOP>Функции, ожидающие ASCIIZ, споткнутся на первом же байте со значением 0. В UTF-16 это скорее всего будет в одном из первых символов.
тю, ну ясен пень. Проблема бабушки в том, что она не дедушка?
А вы запихните UTF-8 строку в wchar_t* и вызовите CreateFile. Интересно, откроется?
Это будет уже проблемой UTF-8?
MOP>>>А вот чем UTF-16 лучше UTF-8? Ничем. Сохраняет недостатки UTF-8 и добавляет свои. S>>в соседней ветке уточняем по поводу доступа по индексу.
MOP>Доступ по индексу — довольно редкая операция (может чуть чаще, чем языкозависимое сравнение строк без учёта регистра). И если нужно — можно и ICU подключить (впрочем, именно для этого есть и полегче библиотеки).
Может. Справедливости ради — сам не сталкивался. Но та же винда внутри этим должна заниматся. при переносе строк и т.п.
S>>Но проблема совместимости так же актуальна и для UTF-8. Здесь вопрос окружения, а не ситуация, если бы S>>везде был UTF-8.
MOP>Это Microsoft создала эту проблему и практически единственная причина для работы с UTF-16 — её обход.
Здравствуйте, Аноним, Вы писали:
А>Подскажите пожалуйста, как в С++ работать со строками в кодировке UTF-8 ? А>(требуется стандартный набор строковых функций — strcmp(), strcat(), strcpy()... )
Здравствуйте, Аноним, Вы писали:
А>Подскажите пожалуйста, как в С++ работать со строками в кодировке UTF-8 ? А>(требуется стандартный набор строковых функций — strcmp(), strcat(), strcpy()... )
также как и с С-строками т.е. char*, абсолютно ничего не меняется, разве что способ кодирования не ASCII символов.
Здравствуйте, Алексей, Вы писали:
А>Здравствуйте, dilmah, Вы писали:
W>>>strcmp(), strcat(), strcpy() будут работать некорректно
D>>с strcmp действительно будут не очень хорошие вещи если нужно чтобы эквивалентные коды считались равными, но работать то все равно будет
А>Вот и нафиг нужен такой язык?
Кодировка это вещь, которая параллельна языку. Например, в C# будет ли "weiß" = "weiss"???
Здравствуйте, sidorov18, Вы писали:
S>Что касается UTF-16 — в каких языках она не покрывает символ/2 байта?
Ну, например, в контонском варианте китайского...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Mystic, Вы писали:
M>Здравствуйте, sidorov18, Вы писали:
MOP>>>UTF-16 во всех смыслах хуже UTF-8.
S>> S>>Скажите хоть пару.
M>Больше места
Врядли вам часто нужно хранить магабайты текста в памяти. Был хоть один такой случай?
Зато все винапи работает с UTF-16. неоднократно встречал упоминание, что изначальные функции для UTF-16. т.е. каждый вызов ANSI версии будет конвертировать вашу строку в UTF-16.
+ если понадобится узнать количество символов в строке или доступ по индексу — моментально вылезут удобства UTF-16.
т.е. удобства UTF-8 появятся только тогда, когда в памяти нужна будет тонна текста. И это еще зависит от того, что с текстом делать потом будуте..
M>все равно символы как двумя байтами, так и четырьмя, надо дополнительно константы из кода переводить в UTF-16 тоже
что значит переводить?
"Василий"//L"Василий"
вот так переводить?
решается макросом _T()
Если, конечно, строка не нужна в двух вариантах, как, например, при отправке HTTP POST запроса, где строку все равно нужно будет в UTF-8 переводить.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, dilmah, Вы писали:
D>>и что же с strstr?
D>>Первый байт любого символа всегда отличается от непервого байта.
PD>А первый байт двухбайтового UTF-8 символа в строке, где ищем, не может совпасть с единственным байтом однобайтного символа в строке , которую ищем ?
В том случае если строка, которую ищем, в отличной кодировке от UTF-8. Только зачем такие приключения?
Здравствуйте, Кодт, Вы писали:
К>Разбивка строки на символы — задача, относящаяся к пользовательскому интерфейсу (начиная с того, куда каретку рисовать) или к весьма специфичной обработке текста. К>В остальных случаях, включая даже неспецифический пользовательский интерфейс (ввод-вывод строки целиком, средствами операционной системы или готовых библиотек) хватает тупой трактовки: строка — массив char'ов или wchar'ов (и пересчитать wchar'ы в байты можно простым умножением на sizeof(wchar_t)). К>Ну и спрашивается, зачем тратить время и память на создание и поддержание структуры данных, которая, вероятнее всего, не понадобится?
Вот практический пример.
Задача — написать библиотеку, которая фильтрует веб-контент и вырезает из него запрещенные слова.
Контент идет на разных языках и в разных кодировках (чаще всего — в UTF-8).
Вот и как тут пользоваться std::string, если она BOM не понимает, нормализацию делать не умеет, и
даже не может преобразовать найденное слово к нижнему/верхнему регистру ?
К>Более того, работа со строкой целиком может внутри скрывать разбор строки на буквы. Но это забота библиотеки, а не пользователя. Указываешь, скажем, текущую локаль de_DE.utf8, и пусть strcoll там эсцеты с умляутами сравнивает по всем правилам.
Visual C++ выбрасывает исключение, если создать локаль с именем "ru_RU.utf8" (другие варианты тоже пробовались).
Здравствуйте, gegMOPO4, Вы писали:
MOP>Здравствуйте, Erop, Вы писали: E>>Ничего не виднеется такого UTF-16-образного?
MOP>Это только одно из окружений...
Дык я про то и говорю, что удобная кодировка, в первую очередь, определяется окружением и задачами, а не какими-то принципиальными преимуществами кодировок.
У UTF-16 и UTF-32 есть небольшое преимущество, состоящее в том, что проще работать с решистрами букв. Но оно редко бывает значимым, тем не менее...
MOP>Ну вот угораздило МС сделать такую ошибку, теперь всем расплачиваться.
Я не считаю, что это прямо вот ошибка-ошибка. Кодировки-то равноправны на самом деле.
В мире лялиха было одобнее UTF-8, а в мире винды нет. Если начинать с читсого листа, то UTF-16 чуть лучше, из-за того, что регистры...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, okman, Вы писали:
O>Нельзя использовать строки std:(w)string для работы с UTF-8. O>Потому что шаблонный тип для basic_string — это char и wchar_t, длина которого фиксирована. O>В Visual C++ это 1 и 2 байта соответственно. А UTF-8 — многобайтовая кодировка, символ в ней O>может быть представлен как одним байтом, так и четырьмя.
Изначально подразумевалось что char'ами представляются символы в мультибайтовой кодировке, а wchar_t'ы должны вмещать в себя любой символ из доступного набора. На практике это не всегда так, UTF-16 в винде — это ужас и моральный террор. Для пруфа см. соответствующие разделы стандарта, приложение о локализации в Страуструпе и напр. http://www.cplusplus.com/reference/std/locale/codecvt/max_length/ — функция как раз возвращает максимальную длину символа. Так что мультибайтовость сама по себе использованию std::string и набора функций из <cstring> не мешает. Другое дело что, например, результат std::string::operator==() не более чем результат побитового сравнения, такой же как и strcmp(), и если необходимо нечто иное, то следует использовать strcoll(), std::locale::collate, std::lexicographical_compare и надеятся что они правильно работают на данной платформе.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Erop, Вы писали:
E>>При этом с регисторм есть такая беда, что всё равно надо знать язык, чтобы понять какие маленькие буквы каким большим соответствуют.
PD>LCMapString PD>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.
PD>int LCMapString( PD> LCID Locale, PD> DWORD dwMapFlags, PD> LPCTSTR lpSrcStr, PD> int cchSrc, PD> LPTSTR lpDestStr, PD> int cchDest PD>);
PD>LCMAP_LOWERCASE For locales and scripts capable of handling uppercase and lowercase, map all characters to lowercase. PD>LCMAP_UPPERCASE For locales and scripts capable of handling uppercase and lowercase, map all characters to uppercase
Ты не то выделил, IMHO...
Как это не печально, но в разных языках РАЗНОЕ соответствие больших букв маленьким. Разное и всё тут, хоть ты тресни.
Так что если язык не знаешь, а знаешь только буквы, например UTF-16, то фиг ты чего сконвертируешь
Примеры "разного"
1) Что делать с SS в немецком.
2) Что делать с диакритикой в язвках, где над большими буквами не пишут диакритических знаков?
3) Буква I бывает с точкой и без точки, как большая, так и маленькая. При этом в некоторых языках, например в турецком, маленькой с точкой соответствуюе большая с точкой, а большой без точки соответствует маленькая, тоже без точки, а вот в некоторых других языках, например в английском, всё перепутано. Большой без точки соответствует маленькая СТОЧКОЙ, и наоборот...
4) И т. д...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
D>>>strcat, strcpy работают без изменений D>>>В дополнение к strcmp есть strcoll, но strcmp тоже работает W>>strcmp(), strcat(), strcpy() будут работать некорректно
D>с чего вдруг?
strcat(), strcpy() будут работать, а вот в strcmp() побайтовое сравнение может дать неверный результат
Здравствуйте, Алексей, Вы писали:
А>Здравствуйте, dilmah, Вы писали:
W>>>strcmp(), strcat(), strcpy() будут работать некорректно
D>>с strcmp действительно будут не очень хорошие вещи если нужно чтобы эквивалентные коды считались равными, но работать то все равно будет
А>Вот и нафиг нужен такой язык?
Язык Си был придуман на 20 лет раньше, чем многобайтные кодировки, а среди разработчиков языка не было пророков, которые могли предсказать такие кодировки. И проблемы с strcmp и UTF-8 могут проявится только если нужна сортировать строки по алфавиту. Но если нужно сортировать строки на Русском языке, то strcmp() в любом случае не подходит, т.к. во всех кодировках кириллицы буква Ё расположена не по алфавиту, а в КОИ-8, все буквы расположены не по алфавиту.
В случае, когда нужно просто сравнить UTF-8 строки на равенство, strcmp() можно использовать.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Нет никаких эквивалентных кодов в UTF-8.
возможно, подразумевалось, что один и тот же символ может представляться разными кодами
The Unicode character set includes numerous combining characters, such as U+0308 ("¨"), a combining dieresis or umlaut. Unicode can often represent the same glyph in either a ''composed'' or a ''decomposed'' form: for example, the composed form of "Ä" is the single Unicode code point "Ä" (U+00C4), while its decomposed form is "A" + "¨" (U+0041 U+0308). Unicode does not define a composed form for every glyph. For example, the Vietnamese lowercase "o" with circumflex and tilde ("ỗ") is represented by U+006f U+0302 U+0303 (o + Circumflex + Tilde). For further discussion of combining characters and related issues, see Using Unicode Normalization to Represent Strings.
O>Правильный подход тут уже указали — нужно подключать сторонние библиотеки вроде ICU и O>использовать те строковые типы, которые они предлагают.
есть у меня опыт работы с "правильным" подходом
так вот выбросили его через два года, ибо устали: тормоза в рантайме и депенд на ICU (как следствие тормоза компиляции, усложнение инсталяторов), а выигрыша ноль
заменили на std::string (UTF8), std::wstring (win)\ std::basic_string<short> (linux) (UTF16) и стало замечательно
софт локализован на 14 языков (включая азиатские), полет нормальный
НО! это касается серверных приложений
ГУЙ, которому нужно переводить слова по строкам, лейаут прорабатывать остался на ICU (хотя в кишках и с std:(w)string работает)
Здравствуйте, 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 лучше не станет.
Здравствуйте, whitewin, Вы писали:
D>>с чего вдруг?
W>strcat(), strcpy() будут работать, а вот в strcmp() побайтовое сравнение может дать неверный результат
Смотря что вы вкладываете в понятие "верный результат".
Оно, конечно, не подходит для сортировки по национальному алфавиту, отличному от латинского, но если сравнение строк нужно, к примеру, с целью поиска, то вполне себе strcmp() работает корректно.
Здравствуйте, Banned by IT, Вы писали: BBI>Здравствуйте, gegMOPO4, Вы писали: MOP>>Фактически единственная операция, где std::string недостаточно — обрезка строки по заданному количеству символов. BBI>И ещё вообще везде где надо знать сколько буковок будет выведено.
…но достаточно u32string…
Нет, для числа буковок строки в UTF-32 недостаточно.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Нет, для числа буковок строки в UTF-32 недостаточно.
Да и само по себе понятие "число буковок" крайне мутное...
Интереснее обсуждать не предрассудки, а задачи. От задачи можно было бы хотя бы понять физ. смысл того "из чисел букв", которое имеется в виду...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, sidorov18, Вы писали:
S>Все таки маленький, но плюс — больше конвертировать или меньше конвертировать..
Ну и распечатать/посмотреть/что-то ещё сделать для отлдаки, например, в винде с UTF-16 строкой проще, чем с UTF-8...
S>>>в соседней ветке уточняем по поводу доступа по индексу.
Доступ по индексу имеет смысл обсуждать, только после того, как поределимся с тем, что такое буква...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, gegMOPO4, Вы писали:
S>>А вы запихните UTF-8 строку в wchar_t* и вызовите CreateFile. Интересно, откроется? S>>Это будет уже проблемой UTF-8?
MOP>Какой ещё CreateFile-Shmile? Мы в форуме C++ или где? fopen, fstream скорее заработают с UTF-8, чем с wchar_t.
Все правильно. Ну так какой был довод такой и контрдовод.
Не суйте UTF-16 туда, где предполагается ANSI и наоорот.
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>А что такое буква? E>От языка зависит...
:-P
C++ и UTF8
От:
Аноним
Дата:
26.10.11 19:47
Оценка:
Подскажите пожалуйста, как в С++ работать со строками в кодировке UTF-8 ?
(требуется стандартный набор строковых функций — strcmp(), strcat(), strcpy()... )
Здравствуйте, dilmah, Вы писали: W>>strcmp(), strcat(), strcpy() будут работать некорректно D>с strcmp действительно будут не очень хорошие вещи если нужно чтобы эквивалентные коды считались равными, но работать то все равно будет
почему? В обычном то юникоде есть? http://en.wikipedia.org/wiki/Unicode_equivalence
А обычный юникод преобразуется в multibyte UTF-8 по четко описанным правилам. Там же нет требования нормализации какой-то или есть?
Здравствуйте, dilmah, Вы писали: MOP>>Нет никаких эквивалентных кодов в UTF-8. D>почему? В обычном то юникоде есть? http://en.wikipedia.org/wiki/Unicode_equivalence D>А обычный юникод преобразуется в multibyte UTF-8 по четко описанным правилам. Там же нет требования нормализации какой-то или есть?
А-а-а, в этом смысле… Ну тогда нужно другой смысл вкладывать в «равенство строк».
Здравствуйте, Аноним, Вы писали:
А>Подскажите пожалуйста, как в С++ работать со строками в кодировке UTF-8 ? А>(требуется стандартный набор строковых функций — strcmp(), strcat(), strcpy()... )
А что именно хочется делать со строками?
Может сразу в UTF-16 переводить?
Здравствуйте, Аноним, Вы писали:
А>Подскажите пожалуйста, как в С++ работать со строками в кодировке UTF-8 ? А>(требуется стандартный набор строковых функций — strcmp(), strcat(), strcpy()... )
Можно использовать стандартные. Одна из проблем в том, что в функции strcmp можно придумать тысячи различных вариантов сравнения строк, не факт, что вариант по умолчанию тебя устроит.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Здравствуйте, sidorov18, Вы писали: S>>Здравствуйте, Аноним, Вы писали: А>>>Подскажите пожалуйста, как в С++ работать со строками в кодировке UTF-8 ? А>>>(требуется стандартный набор строковых функций — strcmp(), strcat(), strcpy()... ) S>>А что именно хочется делать со строками? S>>Может сразу в UTF-16 переводить?
MOP>UTF-16 во всех смыслах хуже UTF-8.
Здравствуйте, gegMOPO4, Вы писали:
MOP>А вот чем UTF-16 лучше UTF-8? Ничем. Сохраняет недостатки UTF-8 и добавляет свои.
ну он лучше, чем UTF-8 тем, что уменьшает вероятность размазывания юникодного символа по нескольким байтам
идеальным в этом плане является UTF-32
Первый байт любого символа всегда отличается от непервого байта. Кроме того если кол-во байтов в символах отличается то их первый байт тоже отличается.
Здравствуйте, uzhas, Вы писали: U>Здравствуйте, gegMOPO4, Вы писали: MOP>>А вот чем UTF-16 лучше UTF-8? Ничем. Сохраняет недостатки UTF-8 и добавляет свои. U>ну он лучше, чем UTF-8 тем, что уменьшает вероятность размазывания юникодного символа по нескольким байтам
Да неужели?! В UTF-8 128 символа (в число которых входят наиболее частые) кодируются одним байтом. В UTF-16 каждый символ размазывается по нескольким байтам.
U>идеальным в этом плане является UTF-32
Здравствуйте, gegMOPO4, Вы писали:
MOP>Да неужели?! В UTF-8 128 символа (в число которых входят наиболее частые) кодируются одним байтом. В UTF-16 каждый символ размазывается по нескольким байтам.
имелось в виду другое: std::basic_string<wchar_t> под виндой подходит для хранения UTF16, в таком случае в один wchar_t влезает бОльше инфы и размазать юникодные символ по двум wchar_t становится сложнее =)
Здравствуйте, watch-maker, Вы писали:
WM>Здравствуйте, sidorov18, Вы писали:
S>>+ если понадобится узнать количество символов в строке или доступ по индексу — моментально вылезут удобства UTF-16.
WM>Это какие же? С UTF-16 при решении данных задач работать так же неудобно как и с UTF-8. WM>Вся разница лишь в том, что в UTF-8 один символ может занимать 1,2,3,4 байта, а в в UTF-16 соответственно 2 или 4 байта.
Для какого языка? Каких нибудь китайских диалектов?
Здравствуйте, uzhas, Вы писали: U>Здравствуйте, gegMOPO4, Вы писали: MOP>>А не с UCS2? U>это было в самых первых виндах U>далее на UTF-16 все же перешли
Т.е. вернулись к тому, из-за чего отказались от UTF-8. Где здесь смайл иронии?
Здравствуйте, 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> — всё равно. Т.е. не всё равно, в последнем случае будет ныть из-за расхода памяти.
Здравствуйте, 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. Во многих случаях можно обойтись без.
Здравствуйте, sidorov18, Вы писали:
S>что значит переводить?
WinAPI вроде как работает в UCS-2. Как минимум, это ограничивает набор символов 65536-ю символами. Но все равно необходимо перевести из UTF-16 в UCS-2. Некоторые кроссплатформенные либы принимают все-таки UTF-8. Ну и под другие OS UTF-8 нативнее.
S>
S>"Василий"//L"Василий"
S>
S>вот так переводить? S>решается макросом _T()
А тогда вопрос, как макрос _T узнает кодировку, в которой набран текст?
Здравствуйте, okman, Вы писали: O>Здравствуйте, gegMOPO4, Вы писали: MOP>>В UTF-8 128 символа (в число которых входят наиболее частые) кодируются одним байтом. O>Китайцы с Вами бы не согласились (см. выделенное).
Даже китайцы пишут программы на языках с английскими ключевыми словами, использую форматы и протоколы, в которых теги, имена параметров и разделители в ASCII. Да и числа наверняка записывают в десятичной системе «арабскими» цифрами.
Здравствуйте, okman, Вы писали:
O>Я думаю, что Вы лукавите. O>Когда мы вызываем string.length, мы хотим длину строки в символах, а не каких-то char-like объектов.
Смотря зачем она нам понадобилась...
В конце концов в юникоде есть такие коды, которые не являются самостоятельным символом, а можифицируют соседний. Например, приписывают к нему диакритический знак. Тебе в длине, которая тебе нужна, надо такие символы модификаторы считать за отдельный символ или нет? А ведь ещё эссет всякие есть. Её за скока буковок считать будем?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, okman, Вы писали:
O>Что передавать аргументом string::find_first_of ?
Смотря что и зачем ты ищешь.
Если, например, речь идёт о регулярном выражении, то пофиг искать строчку на языке букв или на языке байт из UTF-8. Если речь идёт о поиске строки введённой пользователем, то и ищи сразу строку, а не один символ и т. д...
Главное, чего мне не понятно, а что ты хотел бы написать в этом месте ВМЕСТО string::find_first_of "если бы всё было по уму"?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А первый байт двухбайтового UTF-8 символа в строке, где ищем, не может совпасть с единственным байтом однобайтного символа в строке , которую ищем ?
Не может. Там прикольно всё сделано. Все байты уникальные типа.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, dilmah, Вы писали:
D>первый байт однозначно определяет длину всей последующей цепочки.
Кроме того, непервый байт всегда отличается от первого вроде как...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Главное, чего мне не понятно, а что ты хотел бы написать в этом месте ВМЕСТО string::find_first_of "если бы всё было по уму"?
Любой символ юникода. Раз уж речь идет о UTF-8.
Но для этого нужна будет специализация find_first_of.
O>>Когда мы вызываем string.length, мы хотим длину строки в символах, а не каких-то char-like объектов.
E>Смотря зачем она нам понадобилась... E>В конце концов в юникоде есть такие коды, которые не являются самостоятельным символом, а можифицируют соседний. Например, приписывают к нему диакритический знак. Тебе в длине, которая тебе нужна, надо такие символы модификаторы считать за отдельный символ или нет? А ведь ещё эссет всякие есть. Её за скока буковок считать будем?
Выполним std::normalize (гипотетический) и забудем.
Здравствуйте, 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 в уме ?
Здравствуйте, 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?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, 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-образного?
Это только одно из окружений...
Ну вот угораздило МС сделать такую ошибку, теперь всем расплачиваться.
Здравствуйте, 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>В этом и есть отличия.
Ну отличия в задачах и окружениии есть всегда. В этом и состоит работа хорошего инженера, чтобы всё учесть и сделать правильный выбор...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
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
Здравствуйте, gegMOPO4, Вы писали:
MOP>Фактически единственная операция, где std::string недостаточно — обрезка строки по заданному количеству символов.
И ещё вообще везде где надо знать сколько буковок будет выведено.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Erop, Вы писали:
O>>Выполним std::normalize (гипотетический) и забудем.
E>Э-э-э, зачем? Тем более, что в каком-нибудь тайском этот твой std::normalize будет весьма гипотетическим. E>А ещё есть кроейский, например. Там можно буквы блока (слога) писать, как последовательные юникоды, а можно, как один. И чего?
Суть в том, что хоть какого, — плохого или хорошего, — std::normalize в C++ нету.
E>Нипиши правильный локейл и всё будет...
Какой ? К примеру, на Visual C++ любые конструкторы std::locale, инициализированные строками
вроде "ru_RU.utf-8", обламываются.
E>Да используй [ICU], ради Бога, если тебе это нужно/удобно и всё такое. Но это ни разу не единственное верное решение...
Здравствуйте, gegMOPO4, Вы писали:
MOP>В 90% задач toupper/tolower не нужны.
MOP>В 90% оставшихся достаточно toupper/tolower только с ASCII.
MOP>Оставшийся 1% — где действительно нужно, и UTF-16 или UTF-32 сами по себе не помогут
MOP>в 90% его не используют и работают с регистром неправильно.
MOP>Подавляющее большинство токенайзеров (использующих разделители из ASCII) будут работать правильно.
MOP>Это очень специфичные задачи, где могло бы понадобиться.
MOP>Затем, что в подавляющем числе случаев «жонглировать» не нужно.
Когда возражения приводятся в таком ключе, спорить неинтересно.
Здравствуйте, Erop, Вы писали:
O>>Выполним std::normalize (гипотетический) и забудем.
E>Э-э-э, зачем? Тем более, что в каком-нибудь тайском этот твой std::normalize будет весьма гипотетическим. E>А ещё есть кроейский, например. Там можно буквы блока (слога) писать, как последовательные юникоды, а можно, как один. И чего?
Дык есть же std::locale::collate::transform, ни разу не гипотетический.
Здравствуйте, Mystic, Вы писали:
M>Здравствуйте, sidorov18, Вы писали:
S>>что значит переводить? M>WinAPI вроде как работает в UCS-2. Как минимум, это ограничивает набор символов 65536-ю символами. Но все равно необходимо перевести из UTF-16 в UCS-2. Некоторые кроссплатформенные либы принимают все-таки UTF-8. Ну и под другие OS UTF-8 нативнее.
хм. а источник есть?
в википедии написано что UCS-2 использовался до 2000 винды.
UTF-16 is used for text used in the OS API in Microsoft Windows 2000/XP/2003/Vista/CE.[8] Older Windows NT systems (prior to Windows 2000) only support UCS-2.[9]
Здравствуйте, okman, Вы писали:
O>Суть в том, что хоть какого, — плохого или хорошего, — std::normalize в C++ нету.
Суть ещё хуже. Его нет не только в С++, но и нигде. Для юникода нельзя задать такое универсальное отображение, увы и ах...
O>Какой ? К примеру, на Visual C++ любые конструкторы std::locale, инициализированные строками O>вроде "ru_RU.utf-8", обламываются.
Ну ты же сам можешь его реализовать, если библа не поддреживает...
O>Возражал не я, возражали мне.
Не-не-не, ты говорил, что типа так и никак иначе... На это и возражали. Иначе тоже можно. Серебрянной пули и правда не бывает
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Banned by IT, Вы писали:
BBI>И ещё вообще везде где надо знать сколько буковок будет выведено.
А что значит "буковок"? Вот, например, Ы -- это скока буковок?.. А арабское слово, какое-нибудь? А арабское слово с огласовками?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, MescalitoPeyot, Вы писали:
MP>Дык есть же std::locale::collate::transform, ни разу не гипотетический.
Беда тут в том, что во многих случаях вообще нет единственно-правильного представления. Поэтому и функцию нормализации фиг-напишешь...
Вот, например, во-французском языке принято (допустимо и широко используется) опускать диакоритику над большими буквами. Но недопустимо сбрасывать регистр букв в именах собственных.
И как будем нормалайз писать?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, gegMOPO4, Вы писали:
MOP>А вот с этим категорически не соглашусь. Они все неудобны (или удобны) по-разному!
IMHO, сами по себе они примерно эквивалентны, за исключением регистра букв, но у разных библ и API интерфейс в разных кодировках... Вот и вся разница. Есть какая-то ещё?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, sidorov18, Вы писали: S>Поскольку использовалось много COM-а — в противом случае нужно было бы много конвертировать. S>Все таки маленький, но плюс — больше конвертировать или меньше конвертировать..
Согласен. А если это не надо, то и выбор UTF-16 становится намного менее обоснованным.
S>А вы запихните UTF-8 строку в wchar_t* и вызовите CreateFile. Интересно, откроется? S>Это будет уже проблемой UTF-8?
Какой ещё CreateFile-Shmile? Мы в форуме C++ или где? fopen, fstream скорее заработают с UTF-8, чем с wchar_t.
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>А вот с этим категорически не соглашусь. Они все неудобны (или удобны) по-разному! E>IMHO, сами по себе они примерно эквивалентны, за исключением регистра букв, но у разных библ и API интерфейс в разных кодировках... Вот и вся разница. Есть какая-то ещё?..
Дык с тем, что в разном окружении удобно с разными кодировками, никто и не спорит...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, gegMOPO4, Вы писали:
MOP>Какой ещё CreateFile-Shmile? Мы в форуме C++ или где? fopen, fstream скорее заработают с UTF-8, чем с wchar_t.
э-э-э, СТАНДАРТНЫЕ fopen, fstream берут на вход ANSI строку...
Их версия от UTF-8, такое же НЕСТАНДАРТНОЕ расширение, как и версия от wchar_t const* ...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, gegMOPO4, Вы писали:
MOP>Проблемы китайцев WASP не волнуют?
Боюсь, что ты сильно преувеличиваешь проблемы китайцев...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>Какой ещё CreateFile-Shmile? Мы в форуме C++ или где? fopen, fstream скорее заработают с UTF-8, чем с wchar_t. E>э-э-э, СТАНДАРТНЫЕ fopen, fstream берут на вход ANSI строку...
Что такое «ANSI строка»?
The fopen function opens the file whose name is the string pointed to by filename,
and associates a stream with it.
ANSI упоминается только в ссылках на ANSI X3/TR−1−82, ANSI/IEEE 754−1985 и ANSI/IEEE 854−1987.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Что такое «ANSI строка»?
строка сhar'ов, каждый из которых -- отдельная буква...
MOP>The fopen function opens the file whose name is the string pointed to by filename, MOP>and associates a stream with it.
Ты не то смотришь. Ты на определение что такое char смотри
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>э-э-э, СТАНДАРТНЫЕ fopen, fstream берут на вход ANSI строку... E>Их версия от UTF-8, такое же НЕСТАНДАРТНОЕ расширение, как и версия от wchar_t const* ...
Стандартный fopen берет на вход char. Что такое char и как его интерпретировать зависит от локали, быть отдельным байтом мультибайтной кодировки (в т. ч. и UTF-8) ему никто не мешает.
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>Проблемы китайцев WASP не волнуют? E>Боюсь, что ты сильно преувеличиваешь проблемы китайцев...
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>Что такое «ANSI строка»? E>строка сhar'ов, каждый из которых -- отдельная буква...
А что такое буква?
MOP>>The fopen function opens the file whose name is the string pointed to by filename, MOP>>and associates a stream with it. E>Ты не то смотришь. Ты на определение что такое char смотри
Зачем мне определение char, если нужно определение string?
A string is a contiguous sequence of characters terminated by and including the first null
character. The term multibyte string is sometimes used instead to emphasize special
processing given to multibyte characters contained in the string or to avoid confusion
with a wide string. A pointer to a string is a pointer to its initial (lowest addressed)
character. The length of a string is the number of bytes preceding the null character and
the value of a string is the sequence of the values of the contained characters, in order.
Здравствуйте, gegMOPO4, Вы писали:
MOP>А что такое буква?
От языка зависит...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, B0FEE664, Вы писали: BFE>Здравствуйте, gegMOPO4, Вы писали: MOP>>Если начинать с совсем чистого листа, следовало бы делать char 16-битным. Но Ритчи† уже далеко. BFE>Это можно сделать и сейчас. Стандарт позволяет.
Стандарт позволяет, совместимость не позволяет.
Надо бы, надо родить бабу новую,
Светлу, понятну, идейно толковую,
Да грешный наследный вредит геморрой.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Здравствуйте, Erop, Вы писали:
E>>>При этом с регисторм есть такая беда, что всё равно надо знать язык, чтобы понять какие маленькие буквы каким большим соответствуют.
PD>>LCMapString PD>>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.
PD>>int LCMapString( PD>> LCID Locale, PD>> DWORD dwMapFlags, PD>> LPCTSTR lpSrcStr, PD>> int cchSrc, PD>> LPTSTR lpDestStr, PD>> int cchDest PD>>);
E>Ты не то выделил, IMHO...
То.
E>Как это не печально, но в разных языках РАЗНОЕ соответствие больших букв маленьким. Разное и всё тут, хоть ты тресни. E>Так что если язык не знаешь, а знаешь только буквы, например UTF-16, то фиг ты чего сконвертируешь
Именно этим функция и занимается. Как — вопрос к MS. А выделил я не локаль (это очевидно, что она тут нужна), а просто тот факт, что на входе ей можно подавать и Юникод, и ASCII.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Banned by IT, Вы писали:
BBI>>И ещё вообще везде где надо знать сколько буковок будет выведено.
E>А что значит "буковок"? Вот, например, Ы -- это скока буковок?.. А арабское слово, какое-нибудь? А арабское слово с огласовками?
Я так понимаю — это одна буква
Иначе задача бы звучала — количество каракулей.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Здравствуйте, sidorov18, Вы писали: S>>Не суйте UTF-16 туда, где предполагается ANSI и наоорот.
MOP>Не было бы куда совать UTF-16, и проблем бы не было.
И наоборот
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, okman, Вы писали:
O>Вот практический пример. O>Задача — написать библиотеку, которая фильтрует веб-контент и вырезает из него запрещенные слова. O>Контент идет на разных языках и в разных кодировках (чаще всего — в UTF-8). O>Вот и как тут пользоваться std::string, если она BOM не понимает, нормализацию делать не умеет, и O>даже не может преобразовать найденное слово к нижнему/верхнему регистру ?
Берём поток байтов (std::string) в известной нам произвольной кодировке (в том числе 2х- или 4х-байтовой) и приводим к удобной нам универсальной кодировке.
Зачастую достаточно mbtows (перевод в UTF-16 или -32) и, если нам не нравится std::wstring, обратно wstomb в UTF-8.
После этого, зная о языке контента, выполняем нормализацию (вот тут стандартной сишной библиотеки, видимо, уже не хватит), лезем в соответствующий словарь и режем матюки на этом языке.
O>Visual C++ выбрасывает исключение, если создать локаль с именем "ru_RU.utf8" (другие варианты тоже пробовались).
E>>А что значит "буковок"? Вот, например, Ы -- это скока буковок?.. А арабское слово, какое-нибудь? А арабское слово с огласовками?
S>Я так понимаю — это одна буква
Это ты про арабское слов или про арабское слово с огласовками?
А как ты проведёшь граицы букв в тайском, например, где есть такая буква, один из элементов которой вседа пишется над предыдущей?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
PD>Именно этим функция и занимается. Как — вопрос к MS. А выделил я не локаль (это очевидно, что она тут нужна), а просто тот факт, что на входе ей можно подавать и Юникод, и ASCII.
не "юникод", а UTF-16, а вот UTF-8, например, вроде как нельзя
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Это ты про арабское слов или про арабское слово с огласовками?
Думаю — в арабском юникоде это разные символы просто. Не в курсе, как они сделали?
E>А как ты проведёшь граицы букв в тайском, например, где есть такая буква, один из элементов которой вседа пишется над предыдущей?
Пишется — это совсем другое дело. Все, естественно, зависит от задачи, от применения.
Решать абстрактные задачи в вакууме — тут, конечно, можно и задуматься, а что же считать буквой
Здравствуйте, sidorov18, Вы писали:
S>Думаю — в арабском юникоде это разные символы просто. Не в курсе, как они сделали?
Есть коды-модификаторы, добавляющие огласовку к букве...
S>Пишется — это совсем другое дело. Все, естественно, зависит от задачи, от применения. S>Решать абстрактные задачи в вакууме — тут, конечно, можно и задуматься, а что же считать буквой
Ну я вот про тоже самое. Что понятие "буква" хорошо определено далеко не во всех языках...
Дальше начинаем сильно зависеть от задачи и вообще порастаем подробностями. То есть отличия в кодировках становятся несущественны, по сравнению с остальным гемором
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>не "юникод", а UTF-16, а вот UTF-8, например, вроде как нельзя
Это ты где хочешь говори, но только не когда речь идет о функциях Win API. Им на вход подается либо ANSI-строка, либо UNICODE- строка (да, конечно, UTF-16, но терминология здесь именно такая). Никаких UTF-8 строк в Win API нет и передавать их никуда нельзя, кроме как в MultiByteToWideChar и т.п.