C/C++
Годится ли wchar_t для работы со строками UTF-8 в Си?
Некоторые говорят, что будут проблемы с переносимостью, но мне нужно, чтобы программа работала только там, где она уже корректно работает.
Это не имеет смысла. Тебе в любом случае придётся перекодировать из UTF-8 в wchar_t и из wchar_t в UTF-8.
В Windows wchar_t - это 2 байта и кодировка UTF-16LE. А использовать UTF-16 - то ещё "удовольствие". Это пока символов в Unicode было меньше 2¹⁶, кодировка UTF-16 имела смысл, а сейчас суррогатные пары создают куда больше проблем, чем решают.
В Linux wchar_t - 4 байта и там единственная проблема, кроме необходимости перекодировки - объём занимаемой памяти.
Как ни странно, но для хранения UTF-8 в виде UTF-8 лучше всего подходят обычные строки однобайтовых символов. Собственно, кодировка UTF-8 и создавалась для того, чтобы быть максимально совместимой с ними. Да, будет сложнее с определением длины строки в символах и вырезанием подстрок, но в реальных программах это создаёт не столь много проблем.
В Windows wchar_t - это 2 байта и кодировка UTF-16LE. А использовать UTF-16 - то ещё "удовольствие". Это пока символов в Unicode было меньше 2¹⁶, кодировка UTF-16 имела смысл, а сейчас суррогатные пары создают куда больше проблем, чем решают.
В Linux wchar_t - 4 байта и там единственная проблема, кроме необходимости перекодировки - объём занимаемой памяти.
Как ни странно, но для хранения UTF-8 в виде UTF-8 лучше всего подходят обычные строки однобайтовых символов. Собственно, кодировка UTF-8 и создавалась для того, чтобы быть максимально совместимой с ними. Да, будет сложнее с определением длины строки в символах и вырезанием подстрок, но в реальных программах это создаёт не столь много проблем.
Валерий N
В обычный char как я запишу русскоязычный литерал?
https://ru.wikipedia.org/wiki/%D0%A8%D0%B8%D1%80%D0%BE%D0%BA%D0%B8%D0%B9_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB
а так прочти
https://habr.com/ru/post/164193/
«СОВЕТ. Используйте общие типы данных и имена для представления символов и строк.»
TCHAR
а он при выборе кодировки в проекте будет wchar_t.
Вообще:
TCHAR определен так:
#ifdef _UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif
Для винды все норм, вот для «В GNU/Linux тип wchar_t имеет размер 32 бита» надо будет проверить. Но, проблема может быть только для очень специфических символов и стран, так что можно на это не обращать внимание.
Вот проект CLCL счас открыт, у него TCHAR используется везде и японский нормально живет...но это под винду, а под какую систему вы программируете я не знаю. А то пишут ««размер типа wchar_t определяется компилятором, вплоть до минимальных 8 бит.» и значит компилятор имеет значение.
а так прочти
https://habr.com/ru/post/164193/
«СОВЕТ. Используйте общие типы данных и имена для представления символов и строк.»
TCHAR
а он при выборе кодировки в проекте будет wchar_t.
Вообще:
TCHAR определен так:
#ifdef _UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif
Для винды все норм, вот для «В GNU/Linux тип wchar_t имеет размер 32 бита» надо будет проверить. Но, проблема может быть только для очень специфических символов и стран, так что можно на это не обращать внимание.
Вот проект CLCL счас открыт, у него TCHAR используется везде и японский нормально живет...но это под винду, а под какую систему вы программируете я не знаю. А то пишут ««размер типа wchar_t определяется компилятором, вплоть до минимальных 8 бит.» и значит компилятор имеет значение.
По-моему, если кто-то здесь скажет "годится" или "не годится", на это вряд ли можно полагаться. Даже на ресурсы с более высоким качеством информации (stackoverflow) я бы не полагался. Может, у них сработало, а у тебя не сработает.
Я бы провёл эксперимент: забабахал бы программу и скормил ей тексты. Проверь isupper(), toupper(), tolower(), isalpha() (их wchar версии), ввод-вывод в потоки, поиск подстрок, wstrlen, std::wstring и т.п. Нужно проверить на латинице и на русском алфавите.
Я бы провёл эксперимент: забабахал бы программу и скормил ей тексты. Проверь isupper(), toupper(), tolower(), isalpha() (их wchar версии), ввод-вывод в потоки, поиск подстрок, wstrlen, std::wstring и т.п. Нужно проверить на латинице и на русском алфавите.
Достаточно char.
Но для внутренних работ лучше вообще перевести всё в UTF-32
Но для внутренних работ лучше вообще перевести всё в UTF-32
Обычные функции Си и Си++ прекрасно работают со строками в UTF-8. Единственное, что вы не сможете - так это прыгнуть до какого-то символа по индексу, придется ползти до него от начала строки. Если это для вас критично то можно еще подумать насчет преобразования строк в wchar_t а в остальных случаях это нафиг не нужно.
Timur Timur
А это означает, что какие-то библиотеки, прыгающие по индексу, не будут работать из-за такой "мелочи". Всё надо проверять.
Похожие вопросы
- Как конвертировать Char или Tchar или wchar_t в LPWSTR?
- Си. Работа со строками.
- Как в UTF-8 байт последовательности, где англ 1 байт, а рус 2 байта, парсер поймёт что символ русский, а не 2 англ?
- Работа со структурами. Написать программу для СИ
- Работа со строками, поиск слова
- Задача по работе со строками на языке программировании c++
- Переход на следующую строку при считывании данных из файла в Си
- Задача на строки в Си
- Нужно не выводить пробел в конце строки. язык си (Андрей, даже ваш вариант сайт считает не рабочим... )
- Помогите написать код на Си, по теме "строки".