LINUX.ORG.RU

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

 ,


4

3

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

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

★★★★★

где этот @hateyoufeel и почему я должен выполнять его обязанности?

итак, стандарты.

  1. спецификация POSIX глаголит
For the new process image, the equivalent of:

setlocale(LC_ALL, "C")

shall be executed at start-up.

ей вторит C11 §7.11.1.1 The setlocale function

At program startup, the equivalent of

setlocale(LC_ALL, "C");

is executed.

хотите системную? setlocale(LC_ALL, "");

нужна ли вам (системная) локаль или достаточно дефолтной?

а это смотря чего вы хотите. просто вывести букафки на экран? https://godbolt.org/z/oEqcGP1eM

а зачем тогда нужно устанавливать локаль? например затем

double price;
char buf[SZ];
while ( ... )     // processing the German invoice
{
   setlocale(LC_ALL, "en_US");
   fscanf(priceFile,"%lf",&price);
   // convert $ to DM according to the current exchange rate
   setlocale(LC_ALL,"de_DE");
   strfmon(buf,SZ,"%n",price);
   fprintf(invoiceFile,"%s",buf);
}
  1. стандарт Unicode 4.0 говорит нам (цитирую):

ANSI/ISO C оставляет семантику широких символов на усмотрение конкретной реализации

размер типа wchar_t определяется компилятором, вплоть до минимальных 8 бит. Соответственно, приложения, которым требуется сохранять переносимость на различных C и C++ компиляторах, не должны использовать wchar_t для хранения Unicode-текста. Тип wchar_t предназначен для хранения широких символов в том виде, в котором их понимают конкретные компиляторы, и это может не соответствовать Юникоду

всё, можно дальше растекаться.

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

А через десяток лет выяснилось, что wchar_t — это неадекватный способ хранения юникода и обычный char с этим прекрасно справляется, если используется кодировка юникода UTF-8.

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

Вы ещё пожалуйтесь, что ваша программа на C не работает как положено на БК0010. Нужно современными реалиями жить, а не тащить на горбу всякий шлак из прошлого.

Чтобы Си и библиотеки для работы с текстом (про utf-8 я не слова не сказал) работали на разных системах, а не только linux вызов setlocale() оставили на программиста, а уже он решает нужна ли сортировка по алфавиту и регулярки завязаные на локаль.

s-warus ★★
()

Несмотря на то, что такие языки программирования как Python, Ruby и Free Pascal хорошо поддерживают юникод при работе с ним могут возникать трудности у программистов на C и C++.

Шел суровый 2023 год. Программисты C/C++ все так же страдали, выплясывая до кровавых мозолей над строками, которые на самом деле массивы, но массивы из символов, но символы - это не символы а байты, но байты - это не коды, потому что код символа многобайтовый. Вот так легко и просто можно работать с Unicode строками в самих прогрессивных языках, которые придумал человек.

PS: После «юникод» забыта запятая.

Xintrea ★★★★★
()

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

MOPKOBKA ★★★
()

Начиная с C11 можно вместо wchar_t использовать char16_t/char32_t.

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

Так было в ISO 10646, но абсурдность такого подхода стала настолько очевидна, что от в Юникоде от нее отказались.

А в Plan 9 не отказались: там руна = символ. И, соответственно, строка = массив символов.

monk ★★★★★
()
Ответ на: комментарий от s-warus

wchar_t конечно не является золотой пулей, но в некоторых задачах не заменим

В задачах работы с протухшим легаси? Конечно, незаменим. Вопрос в том, зачем с протухшим легаси иметь дело.

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

Напоминаешь одного, использует профессионально web-фреймворк, но что такое css и html - тёмный лес - это тёмное легаси.
То что, ты не встречал проблем, нипочём не говорит.
Инструменты использующие wchar_t изолируют тебя от его использования.
В малоизвестной и протухшей для тебя библиотеке Boost работа с интерциональными символами, идёт с помощью широких (UChar32) символов, для utf-8 есть только конвертация в UChar32 и обратно, что может немного тебя убедит, что в некоторых задачах utf-8 крайне не удобен.

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

В малоизвестной и протухшей для тебя библиотеке Boost работа с интерциональными символами, идёт с помощью широких (UChar32) символов, для utf-8 есть только конвертация в UChar32 и обратно, что может немного тебя убедит, что в некоторых задачах utf-8 крайне не удобен.

Они как раз продвигают UTF-8: https://www.boost.org/doc/libs/1_83_0/libs/locale/doc/html/recommendations_and_myths.html

monk ★★★★★
()
Ответ на: комментарий от s-warus

библиотеке Boost работа с интерциональными символами, идёт с помощью широких (UChar32) символов

boost::locale::generator gen;
using namespace boost::locale::boundary;
std::string text="生きるか死ぬか、それが問題だ。";
ssegment_index map(word,text.begin(),text.end(),gen("ja_JP.UTF-8"));
for(ssegment_index::iterator it=map.begin(),e=map.end();it!=e;++it) {
    std::cout << "Segment " << *it << " contains: ";
    if(it->rule() & word_none)
        std::cout << "white space or punctuation marks ";
    if(it->rule() & word_kana)
        std::cout << "kana characters ";
    if(it->rule() & word_ideo)
        std::cout << "ideographic characters";
    std::cout<< std::endl;
}

Would print:

Segment 生 contains: ideographic characters
Segment きるか contains: kana characters
Segment 死 contains: ideographic characters
Segment ぬか contains: kana characters
Segment 、 contains: white space or punctuation marks
Segment それが contains: kana characters
Segment 問題 contains: ideographic characters
Segment だ contains: kana characters
Segment 。 contains: white space or punctuation marks

Где?

monk ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.