Здравствуйте. В связи с работой над одним проектом, возник вопрос в реализации класса строки.
Реализация должна быть кроссплатформенной. Необходима поддержка всех доступных языков,
т.е. ascii не подходит. Задача данного вопроса — узнать возможные варианты реализации
класса, их плюсы и минусы.
Варианты решения:
1) Класс-обертка, который хранит строку как последовательность wchar_t символов.
Здесь хотелось бы узнать плюсы или минусы данного варианта.
2) Класс-обертка, который хранит строку как последовательность char символов, но в
кодировке utf-8. Реализовать конвертеры в другие кодировки.
Здесь хотелось бы узнать плюсы или минусы данного варианта.
3) Другой вариант (который вы считаете лучшим).
Я не прошу вас реализовывать данный класс, просто хотелось бы систематизировать данные
по этому вопросу. Надеюсь на конструктивные ответы.
Всем спасибо.
P.S. Пожалуйста, не предлагайте использовать уже существующие классы из сторонних библиотек,
такие как QString и т.п.
WW>Здравствуйте. В связи с работой над одним проектом, возник вопрос в реализации класса строки. WW>Реализация должна быть кроссплатформенной. Необходима поддержка всех доступных языков, WW>т.е. ascii не подходит. Задача данного вопроса — узнать возможные варианты реализации WW>класса, их плюсы и минусы.
WW>Варианты решения:
WW>1) Класс-обертка, который хранит строку как последовательность wchar_t символов. WW>Здесь хотелось бы узнать плюсы или минусы данного варианта.
WW>2) Класс-обертка, который хранит строку как последовательность char символов, но в WW>кодировке utf-8. Реализовать конвертеры в другие кодировки. WW>Здесь хотелось бы узнать плюсы или минусы данного варианта.
WW>3) Другой вариант (который вы считаете лучшим).
WW>Я не прошу вас реализовывать данный класс, просто хотелось бы систематизировать данные WW>по этому вопросу. Надеюсь на конструктивные ответы. WW>Всем спасибо.
WW>P.S. Пожалуйста, не предлагайте использовать уже существующие классы из сторонних библиотек, WW>такие как QString и т.п.
Есть std::string + куча наворотов в последних стандартах. Есть QT QString — со своими наворотами.
Здравствуйте, WerWoolf, Вы писали:
WW>Ну я бы не сказал что их куча. WW>1) есть строковые литералы типа: u8, u, U для кодировок UTF WW>2) есть конвертеры std::codecvt и наследники.
WW>Больше ничего на ум не приходит.
Смотри QString.
Просто задач, где нужна конвертация в другую кодировку — ... не знаю.
Здравствуйте, omgOnoz, Вы писали:
O>Просто задач, где нужна конвертация в другую кодировку — ... не знаю.
O>Я привык, что по умолчанию, весь текст в UTF-8
Ну да, по задаче мне тоже конвертация не часто нужна.
Просто тут могут быть проблемы: допустим я использую std::string, и он отлично будет работать
для одно байтовых кодировок.
Пример:
Здравствуйте, WerWoolf, Вы писали:
WW>Здравствуйте. В связи с работой над одним проектом, возник вопрос в реализации класса строки.
Если тебе от строки нужен только контейнер, то храни все в std::string в utf-8. Если тебе нужно итерировать по буквам, делать некие преобразования и т.д., то сам ты писать умаешься — посмотри ICU, чтобы оценить объем работы.
Здравствуйте, WerWoolf, Вы писали:
WW>Ну да, по задаче мне тоже конвертация не часто нужна. WW>Просто тут могут быть проблемы: допустим я использую std::string, и он отлично будет работать WW>для одно байтовых кодировок. WW>Пример:
WW>std::string str1 = u"abc"; WW>std::string str2 = u"абв";
WW>str1.length() = ? WW>str2.length() = ?
WW>могу предположить, что они не будут одинаковы.
Да эта проблема не решаема с помощью стандартной библиотеки. Смотри ниже.
Использование сторонних библиотек, особенно тяжеловесных, не желательно.
Может есть что-нибудь легковесное, и с бесплатной лицензией. Чтобы его можно
было переделать и внедрить в свой проект?
Здравствуйте, WerWoolf, Вы писали:
WW>Использование сторонних библиотек, особенно тяжеловесных, не желательно. WW>Может есть что-нибудь легковесное, и с бесплатной лицензией. Чтобы его можно WW>было переделать и внедрить в свой проект?
ICU можно использовать, как отдельную-системную библиотеку.
Но на венде выглядит так, что каждый тянет с собой свою копию библиотеке. На линуксе тоже свои приколы.
Здравствуйте, WerWoolf, Вы писали:
WW>std::string str1 = u"abc"; WW>std::string str2 = u"абв";
WW>str1.length() = ? WW>str2.length() = ?
WW>могу предположить, что они не будут одинаковы.
А точно будут ситуации, когда это важно? Ещё надо помнить, что в юникоде длина строки в байтах, code points, буквах и глифах может быть четырьмя различными числами.
Здравствуйте, Don Reba, Вы писали:
DR>А точно будут ситуации, когда это важно?
В принципе да, такие ситуации будут.
Такие базовые вещи, как поиск подстроки, замена и др., как мне кажется могут
потребовать длину строки в в символах.
Здравствуйте, WerWoolf, Вы писали:
WW>В принципе да, такие ситуации будут. WW>Такие базовые вещи, как поиск подстроки, замена и др., как мне кажется могут WW>потребовать длину строки в в символах.
Здравствуйте, WerWoolf, Вы писали:
WW>А чем плох вариант всюду использовать wchar_t? WW>Стандарт насколько мне известно гарантирует, что один wchar_t должен соответствовать одному символу.
Под Windows wchar_t 16 байтов, чего не достаточно для покрытия всего юникода. Плюс, один символ может быть выражен последовательностью юникодовых значений. Более того, один и тот же символ может быть выражен различными последовательностями. С текстом сложно правильно работать.
Здравствуйте, Don Reba, Вы писали:
DR>Под Windows wchar_t 16 байтов, чего не достаточно для покрытия всего юникода. Плюс, один символ может быть выражен последовательностью юникодовых значений. Более того, один и тот же символ может быть выражен различными последовательностями. С текстом сложно правильно работать.
Разве 32-битный wchar не гарантирует полного покрытия всех словарей? Что мешает определить свой std::string для полного слова?
Здравствуйте, Went, Вы писали:
W>Разве 32-битный wchar не гарантирует полного покрытия всех словарей? Что мешает определить свой std::string для полного слова?
Здравствуйте, Don Reba, Вы писали:
DR>Можно определить свой basic_string<uint32_t>, но это не отменяет существования combining character sequences.
В википедии пишут, что на UTF-32 такие фокусы не распространяются. Врут?
Здравствуйте, Went, Вы писали:
DR>>Можно определить свой basic_string<uint32_t>, но это не отменяет существования combining character sequences.
W>В википедии пишут, что на UTF-32 такие фокусы не распространяются. Врут?
UTF32 — это о кодировке и не имеет отношения к combining character sequences.
UTF-32 does not make calculating the displayed width of a string easier, since even with a “fixed width” font there may be more than one code point per character position (combining marks) or more than one character position per code point (for example CJK ideographs).
Здравствуйте, Don Reba, Вы писали:
DR>UTF32 — это о кодировке и не имеет отношения к combining character sequences. DR>https://en.wikipedia.org/wiki/UTF-32
А, то есть некоторые символы могут быть записаны последовательностями 32-битных чаров, но для них, как правило, существует одночаровый эквивалент (кроме самых экзотических случаев)?
Здравствуйте, Went, Вы писали:
W>А, то есть некоторые символы могут быть записаны последовательностями 32-битных чаров, но для них, как правило, существует одночаровый эквивалент (кроме самых экзотических случаев)?
Можно и так сказать. ICU умеет приводить различные варианты записи таких символов к одному варианту когда это возможно.
Здравствуйте, WerWoolf, Вы писали:
WW>Здравствуйте. В связи с работой над одним проектом, возник вопрос в реализации класса строки. WW>Реализация должна быть кроссплатформенной. Необходима поддержка всех доступных языков, WW>т.е. ascii не подходит. Задача данного вопроса — узнать возможные варианты реализации WW>класса, их плюсы и минусы.
WW>Варианты решения:
WW>1) Класс-обертка, который хранит строку как последовательность wchar_t символов. WW>Здесь хотелось бы узнать плюсы или минусы данного варианта.
WW>2) Класс-обертка, который хранит строку как последовательность char символов, но в WW>кодировке utf-8. Реализовать конвертеры в другие кодировки. WW>Здесь хотелось бы узнать плюсы или минусы данного варианта.
WW>3) Другой вариант (который вы считаете лучшим).
WW>Я не прошу вас реализовывать данный класс, просто хотелось бы систематизировать данные WW>по этому вопросу. Надеюсь на конструктивные ответы. WW>Всем спасибо.
WW>P.S. Пожалуйста, не предлагайте использовать уже существующие классы из сторонних библиотек, WW>такие как QString и т.п.
И std::string и std::wstring кросс-платформены и могут хранить любые символы до тех пор пока вы их интерпретируете как UTF-8 и UTF-16.
Обычно внутри программы (системы) имеет смысл принять один из вышеперечисленных и и спользовать его. А вовне отдавать конвертируя в нативное представление.
На Виндах нативное обычно UTF-16, в прочих больше прижилось UTF-8. Самый головняк, что стандартная библиотека MSVC поддерживает UTF-16, но UTF-8 не понимает считая его ANSI, а в остальных банально нету во многих местах поддржки UTF-16 (типа открыть файл/стрим). Это если конечно ниче не поменялось.
Поэтому пока у вас задача только хранить (и неизвестно надо ли еще чего-то) выберите кодировку и успокойтесь. Как надо будет что-то еще — ICU обычно хорошее решение, но часто можно обойтись и системным API.
Здравствуйте, saf_e, Вы писали:
_>И std::string и std::wstring кросс-платформены
все же std::wstring я бы не назвал кроссплатформенным из-за разного размера wchar_t у VS и gcc. в частности, на линуксе std::wstring часто интерпретируется, как UTF-32, а на винде, как UTF-16 (или как UCS-2)
по теме: многое зависит от сценариев использования. универсальных строк нет, у всех есть свои преимущества и недостатки.
лично я по дефолту использую basic_string, т.к. это стандартно (нет внешних зависимостей) и минимум накладных расходов; и пишу я обычно серверный софт (пусть даже и локализованный). использовать в юникодном гуе icu или другие жирные строки считаю нормальным ибо в гуе обычно перформанс не так важен, а корректность работы с разными языками важнее.
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, saf_e, Вы писали:
_>>И std::string и std::wstring кросс-платформены
U>все же std::wstring я бы не назвал кроссплатформенным из-за разного размера wchar_t у VS и gcc. в частности, на линуксе std::wstring часто интерпретируется, как UTF-32, а на винде, как UTF-16 (или как UCS-2) U>по теме: многое зависит от сценариев использования. универсальных строк нет, у всех есть свои преимущества и недостатки. U>лично я по дефолту использую basic_string, т.к. это стандартно (нет внешних зависимостей) и минимум накладных расходов; и пишу я обычно серверный софт (пусть даже и локализованный). использовать в юникодном гуе icu или другие жирные строки считаю нормальным ибо в гуе обычно перформанс не так важен, а корректность работы с разными языками важнее.
на счет std::wstring согласен, этот нюанс нужно учесть при сериализации, как только они в памяти дальше разницы нет.
Здравствуйте, VTT, Вы писали:
VTT>а там случаем BOM не добавляется в начало строки?
Ну, судя по выводу, при использовании литерала u8, BOM в начало не добавляется.
Это кодировка 65001 думает, что в начале идет BOM, пытается прочитать его,
а остальное выводит нормально. Тогда хотелось бы найти кодировку UTF-8 без BOM.
Здравствуйте, WerWoolf, Вы писали:
WW>А чем плох вариант всюду использовать wchar_t? WW>Стандарт, насколько мне известно, гарантирует, что один wchar_t должен соответствовать одному символу.
Нет, не гарантирует.
Это гарантируется только для языков кроме китайского. Подробнее смотри в стандарте Unicode.
Здравствуйте, WerWoolf, Вы писали:
WW>Здравствуйте. В связи с работой над одним проектом, возник вопрос в реализации класса строки. WW>Реализация должна быть кроссплатформенной. Необходима поддержка всех доступных языков, WW>т.е. ascii не подходит. Задача данного вопроса — узнать возможные варианты реализации WW>класса, их плюсы и минусы.
WW>Варианты решения:
WW>1) Класс-обертка, который хранит строку как последовательность wchar_t символов. WW>Здесь хотелось бы узнать плюсы или минусы данного варианта.
WW>2) Класс-обертка, который хранит строку как последовательность char символов, но в WW>кодировке utf-8. Реализовать конвертеры в другие кодировки. WW>Здесь хотелось бы узнать плюсы или минусы данного варианта.
WW>3) Другой вариант (который вы считаете лучшим).
WW>Я не прошу вас реализовывать данный класс, просто хотелось бы систематизировать данные WW>по этому вопросу. Надеюсь на конструктивные ответы. WW>Всем спасибо.
WW>P.S. Пожалуйста, не предлагайте использовать уже существующие классы из сторонних библиотек, WW>такие как QString и т.п.
Здравствуйте, WerWoolf, Вы писали:
WW>2) Класс-обертка, который хранит строку как последовательность char символов, но в WW>кодировке utf-8. Реализовать конвертеры в другие кодировки. WW>Здесь хотелось бы узнать плюсы или минусы данного варианта.