LINUX.ORG.RU

Написал статью «Как жить если у вас юникод»

 ,


5

4

Собственно, сабж. Статья про то самое, что мы с Eddy_Em не могли осилить в прежние времена. В этом году я это, внезапно, осилил. Ну и написал статью.

https://saahriktu.ru/pdf/kak_jit_esli_u_vas_yunikod.pdf

★★★★★

Ответ на: комментарий от Dimez

Буквари и практика не всегда совпадают.

Возможно, авторы этих букварей просто не работают с юникодными строками как с юникодными. Т.е. просто загоняют строки в UTF-8 в char* строки и дальше просто их выводят. А у нас с Eddy_Em были другие вопросы, которые решаются именно так.

saahriktu ★★★★★
() автор топика
Попытка соединения не удалась

При соединении с saahriktu.ru произошла ошибка. 

Возможно, сайт временно недоступен или перегружен запросами. Подождите некоторое время и попробуйте снова.
Если вы не можете загрузить ни одну страницу – проверьте настройки соединения с Интернетом.
Если ваш компьютер или сеть защищены межсетевым экраном или прокси-сервером – убедитесь, что Firefox разрешён выход в Интернет.

Через VPN сайт недоступен, из Австрии не достучаться например. Без VPN работает. У хостера какие то региональные ограничения есть?

Jameson ★★★★★
()

Я не понял, почему там больше слов, нежели «радоваться и не забивать себе голову отныне решёнными проблемами»

XMs ★★★★★
()
Ответ на: комментарий от saahriktu

та то что в техе и так сразу видно, не обращай внимания, у людей нет ответа в чем распространять статьи, но они по привычке фыркают в сотону пдф. хотя прекрасно осознают, что иного варианта сейчас и нет фактически

Morin ★★★★
()

Локалью не надо управлять изнутри, она предназначена для того, чтобы ею управляли снаружи. Ну, либо надо читать переменные окружения, и использовать их значения. Но мне кажется, что это и так делает стандартная библиотека.

Shushundr ★★★
()
Ответ на: комментарий от saahriktu

wchar_t - кроссплатформенный

GNU/Linux один символ wchar_t - 4 байта, а в винде 2 байта

И какой же он тогда кроссплатформенный? Там где линуксовый софт запишет 32 бита виндовый прочитает только 16.

dvetutnev
()
Ответ на: комментарий от Shushundr

Выставление локали в контексте программы не меняет локаль снаружи.

Переменные окружения у shell'а. А при старте программы у неё свои дефолтные значения, которые можно переинициализировать чтобы они начали соответствовать тому, что снаружи.

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от dvetutnev

Сам тип данных есть на всех платформах. Ну, а если нужна полная кроссплатформенность, то ограничения по проверочным условиям в помощь.

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от saahriktu

Мне непонятно зачем им пользоваться, если можно держать UTF-8 в обычном char* и писать код, работающий с plain ASCII и с UTF-8 совершенно одинаково.

Xenius ★★★★★
()
Последнее исправление: Xenius (всего исправлений: 1)

Мое мнение - не нужно натягивать майкрософтские понимания стандартов на весь остальной мир. Использовать в качестве базового символа данных типа wchar_t плохая затея, как раз из-за разной разрядности.

dvetutnev
()
Ответ на: комментарий от Xenius

Мне непонятно зачем им пользоваться, если можно держать UTF-8 в обычном char* и писать код, работающий с plain ASCII и с UTF-8 совершенно одинаково.

Я думаю это майкрософтские импринтинги) Ты правильно говоришь, UTF-8 и храниться в виде последовательности байт, и английский в UTF-8 всегда остается английским не превращаясь кракозябры.

dvetutnev
()
Последнее исправление: dvetutnev (всего исправлений: 1)
Ответ на: комментарий от Xenius

зачем им пользоваться, если можно держать UTF-8 в обычном char* и писать код, работающий с plain ASCII и с UTF-8 совершенно одинаково.

Да нее. Wchar_t это и есть как раз попытка сделать работу с утф-8 «совершенно одинаковой» с анси.
Т.е. чтобы точно так же индексоваться str[i] и т.д. всего лишь поменяв тип(а на самом деле всего лишь поменяв дефайн вначале программы который задаст тип для строк).

В случае если ты хранишь UTF8 в char то такой трюк str[i] = 'ф' уже не прокатит

Bad_ptr ★★★★★
()
Последнее исправление: Bad_ptr (всего исправлений: 2)
Ответ на: комментарий от Xenius

Затем, что char - это один байт. А юникодные символы в один байт не влазят, что усложняет работу с юникодными строками. Даже длину строки в юникодных символах без прохождения по всей строке узнать нельзя. В общем, в прежние годы мы тут приводили полный список проблем, которые решаются только уходом от использования char*. А вместо char* для юникодных строк новый стандарт Си предлагает именно wchar_t. Тот же Python для работы со строками под капотом юзает именно wchar_t. Поэтому де-факто стандартом индустрии теперь является конкретно wchar_t.

saahriktu ★★★★★
() автор топика
Последнее исправление: saahriktu (всего исправлений: 1)
Ответ на: комментарий от Bad_ptr

Да нее. Wchar_t это и есть как раз попытка сделать работу с утф-8

Так задумывалось. В wchar_t должен целиком символ юникода влезать. Но Майкрософт как всегда решил «мы пойдем своим путем», сделала свой API в UTF-16 и не стал расширять wchar_t до 32 бит. И теперь при переносе виндовых проектов на юниксы постоянно имеем проблемы со строками в UTF-16.

dvetutnev
()
Ответ на: комментарий от dvetutnev

wchar_t не Microsoft придумал. То, что у него своя реализация, не значит, что wchar_t в принципе плохой и им не стоит пользоваться.

Конкретно для линуксоидов пишущих под GNU/Linux вообще никаких проблем от использования wchar_t нет. Проблемы могут начаться если возникнет желание портировать этот софт на винду. А это уже, можно сказать, проблемы виндузятников.

saahriktu ★★★★★
() автор топика
Последнее исправление: saahriktu (всего исправлений: 1)
Ответ на: комментарий от saahriktu

wchar_t не Microsoft придумал

Но майкрософт додумался его 16-битным оставить. Как и long не расширил до 64 бит на 64-битной платформе чем доставил кучу проблем.

Проблемы могут начаться если возникнет желание портировать этот софт на винду. А это уже, можно сказать, проблемы виндузятников.

Обычно как раз наоборот) В юниксах как правило UTF-8 на стыках подсистем используют, а вот виндовых проектах этого whcar_t обычно навалом.

dvetutnev
()
Последнее исправление: dvetutnev (всего исправлений: 1)
Ответ на: комментарий от saahriktu

Затем, что char - это один байт. А юникодные символы в один байт не влазят, что усложняет работу с юникодными строками.

Я в курсе, но 99% «работы» со строками — это просто вывести нужную строку.

Даже длину строки в юникодных символах без прохождения по всей строке узнать нельзя.

Ну так пройтись по всей строке, значит, почему нет? Можно оформить в функцию. Да, это медленнее, O(n) вместо O(1), но разве так часто нужно узнавать длину юникодных строк? Обычно достаточно вывести на stdout или в файл и всё.

В общем, в прежние годы мы тут приводили полный список проблем, которые решаются только уходом от использования char*

И какие из этих проблем серьёзные? Какие из них нельзя решить подключением библиотеки со строковыми функциями, работающими с UTF-8?

Xenius ★★★★★
()
Ответ на: комментарий от saahriktu

Даже длину строки в юникодных символах без прохождения по всей строке узнать нельзя.

Я тебе раскрою жирный секрет: даже с прохождением всей строки длину строки узнать нельзя, потому что длина строки в юникоде – крайне неоднозначное понятие.

hateyoufeel ★★★★★
()
Ответ на: комментарий от dvetutnev

И теперь при переносе виндовых проектов на юниксы постоянно имеем проблемы со строками в UTF-16.

А какие проблемы? По идее для символов в пределах BMP пофиг должно быть, а это почти всё кроме экзотики вроде критского линейного письма и ненужной фигни вроде эмодзи.

Xenius ★★★★★
()
Ответ на: комментарий от Xenius

Да, это медленнее, O(n) вместо O(1), но разве так часто нужно узнавать длину юникодных строк? Обычно достаточно вывести на stdout или в файл и всё.

Сишники до сих пор не могут дойти до простого

typedef struct string {
  size_t size;
  void *buf;
} string;
hateyoufeel ★★★★★
()

Тема не раскрыта. Где char8_t для UTF-8 строк? Где конвертация между широкими строками, узкими строками, UTF-8 строками? Статья просто неявно считает, что все локали имеют чарсет UTF-8.

iliyap ★★★★★
()
Ответ на: комментарий от hateyoufeel

неделя открытий на ЛОР-е.

то внезапно сишечка отакот может, ля, в ядро смержили аш.

то вот ля кака строка, ну гениально ж.

нобелевский комитет срочно вносит дополнения в регламент, шоб дать возможность гению в области ойти сорить крупными купюрами.

миленькие мои, открытиям вашим триста лет в обед, приблизительно.

то шо вы тут слегка сбрендили на чтении стандартов - оно канешна хорошо, энтузиазм прекрасен сам по себе и какой-никакой след в душе эти экзерсисы оставят.

но читать надо не только это. и не K&R одним.

код надо читать. и писать. писать и читать. код.

о сколько нам открытий чудных
готовят просвещенья дух
и опыт - сын ошибок трудных
и гений  - парадоксов друг.

            А.С. Пушкин

с максимально добрыми пожеланиями.

olelookoe ★★★
()
Ответ на: комментарий от olelookoe

Даже старыми технологиями ещё нужно научиться пользоваться. Поэтому статьи могут писаться по сколько угодно древним технологиям. Хотя что-то другое кроме char* в массы пошло не так давно, и отсюда множество недопониманий.

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от Xenius

почему нет?

Костыли городить, конечно, никто не запрещает, но это не True way. Особенно после языков программирования где есть строковый тип, включая Python и Паскаль.

Если в Си нет строкового типа и строки - массивы отдельных элементов, то один отдельный элемент массива должен вмещать в себя один отдельный символ, иначе и вырисовываются костыли при работе с такими строками.

Поэтому те, кто избегают юзать wchar_t в Си, я считаю, должны переписать свои проекты с Си на Паскаль. Сам я не вижу проблем в использовании wchar_t в Си, потому и написал сабжевую статью о том, как его юзать. Так что, я могу спокойно писать как на Паскале, так и на Си.

saahriktu ★★★★★
() автор топика
Последнее исправление: saahriktu (всего исправлений: 1)
Ответ на: комментарий от saahriktu

То, из чего состоят строки. Один отдельный элемент.

Юникодные строки состоят из code points, которые могут кодировать глифы, символы или чёрта лысого. Букву Й, например, можно закодировать как кириллическую Й, или как кириллическую И плюс отдельную душку сверху, или ещё десятком разных способов. И во всех случаях при выводе на экран ты получишь Й.

Так что длина строки в юникоде – понятие очень растяживое и зависит от контекста.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)