LINUX.ORG.RU

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

 ,


5

4

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

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

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

Открой исходники какого-нибудь вейланда

ну вон пошарился, какие-то хеш таблицы у них есть

https://gitlab.freedesktop.org/wayland/wayland/-/blob/3175e91efa4d4cb1847044f9ea4a8ef57fd6f39c/src/wayland-hash.c

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

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

Мало линуксоидов. Портируют в свою винду то, что пишут через WSL.

А если линуксоид пишет конкретно под свой GNU/Linux, то проблемы портируемости его не так уж и волнуют.

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

А если линуксоид пишет конкретно под свой GNU/Linux, то проблемы портируемости его не так уж и волнуют.

Я понимаю что тебя не очень волнует портируемость твоего софта, потому что его никто не использует. А всех остальных волнует :D

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

Открой исходники какого-нибудь вейланда

ну вон пошарился, какие-то хеш таблицы у них есть

https://gitlab.freedesktop.org/wayland/wayland/-/blob/3175e91efa4d4cb1847044f9ea4a8ef57fd6f39c/src/wayland-hash.c

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

Удивительно, что в стандартной библиотеке этого до сих пор нет.

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

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

Я считаю, что софт может быть и для красноглазиков. И нет такой обязанности у софта выходить за пределы одной платформы. Т.е. если мне скажут, что, например, мой софт не собирается во FreeBSD, то это меня не очень огорчит, поскольку у меня и не было такой задачи, чтобы он собирался вне GNU/Linux'а. Собирается - хорошо, не собирается - ну и ладно, я под них и не писал.

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

Я считаю, что софт может быть и для красноглазиков. И нет такой обязанности у софта выходить за пределы одной платформы. Т.е. если мне скажут, что, например, мой софт не собирается во FreeBSD, то это меня не очень огорчит, поскольку у меня и не было такой задачи, чтобы он собирался вне GNU/Linux’а. Собирается - хорошо, не собирается - ну и ладно, я под них и не писал.

Это прекрасно, только то что ты выше написал не работает.

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

Для строки «Yes 重要» она вернет 8.

Иероглифы широкие. Каждый из них в ширину занимает 2 знакоместа в консоли. Отсюда и 8.

Т.е., да, как бы, не совсем глифы, но не совсем не глифы. Если выделить место соответствующей ширины для строки, то ошибки не будет.

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

Т.е., да, как бы, не совсем глифы, но не совсем не глифы

Что за бред я только что прочитал?

Если выделить место соответствующей ширины для строки, то ошибки не будет.

А если мне надо посчитать количество глифов – будет. Короче, перестань делать вид что wchar_t это API для работы с юникодом. Это не так. Это просто артефакт из прошлого который попытались натянуть на Юникод как смогли. Вышло плохо.

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

Для чего считают глифы? Чтобы выделить соответствующее место на экране. В той же консоли, например.

Вот эта функция и считает сколько знакомест в консоли надо выделить чтобы строка влезла.

И уже в этом случае «погрешность» возникает именно потому, что символы широкие, т.е. они в одно знакоместо не влазят, им надо по 2 знакоместа.

В общем, везде свои погрешности. Даже «0.1 + 0.2» в Python'е не равно 0.3. И число π до последней цифры мы никогда не узнаем.

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

Между прочим, wcwidth.wcswidth() в Python'е тоже возвращает 8.

len() возвращает 6, но, как было замечено выше, она не со всем юникодом нормально работает, поскольку не все символы влазят в один кодепоинт. Куча составных.

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

Удивительно, что в стандартной библиотеке этого до сих пор нет

ну не то чтобы совсем нет

hcreate, hdestroy, hsearch - в POSIX

Только это не хэш-таблица. И не стандартная библиотека языка.

Ух лул…

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

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

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

Даже «0.1 + 0.2» в Python’е не равно 0.3.

Охлолжежтыблин!

 ▲ ~ python
Python 3.10.12 (main, Jun  6 2023, 22:43:10) [GCC 12.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from decimal import *
>>> Decimal('0.1') + Decimal('0.2')
Decimal('0.3')

И число π до последней цифры мы никогда не узнаем.

Щща.. в Старый Оскол завезут траву по-забористее, и ты нам стопудов последнюю цифру скажешь.

Не так как планировалось изначально в 1990-х. Изначально она возвращала кол-во видимых символов в строке.

Нет не возвращала. Ты ещё блин \t за один символ при выводе на экран начни считать.

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

Между прочим, wcwidth.wcswidth() в Python’е тоже возвращает 8.

Конечно возвращает. Потому что в мане этой функции написано вот это:

determine columns needed for a fixed-size wide-character string

Про глифы тут речи вообще не идет.

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

Дык символы разные бывают. Поэтому видимую ширину строки изначально никто не подразумевал. Подразумевалось сколько вообще данных соответствующих видимым и неотображаемым символам в строке. Это уже с появлением юникода понятие «символ» начало размываться, поскольку теперь всё из кодепоинтов составляется. Поэтому мы теперь вводим понятие «глиф» и удивляемся почему всё ничему не соответствует. Потому, что каша.

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

Это уже с появлением юникода понятие «символ» начало размываться, поскольку теперь всё из кодепоинтов составляется. Поэтому мы теперь вводим понятие «глиф» и удивляемся почему всё ничему не соответствует. Потому, что каша.

Каша у тебя в голове. В юникоде всё норм.

Дефолтна обычная арифметика.

Ваще ни разу. Это лишь особенность реализации.

Алсо, если ты будешь с помощью float считать деньги, например, я лично приду и сломаю тебе руки куском арматуры.

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

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

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

Ваще ни разу. Это лишь особенность реализации.

Без «import decimal» не работает. Это сторонняя библиотека. Под капотом которой своё. Так можно на любую стороннюю библиотеку ссылаться. В то время как в языке из коробки другое.

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

Так это Вы утверждаете, что у Вас всё работает без wchar_t, а у меня с wchar_t не работает.

Вот я и говорю: где хоть один рабочий пример для юникода? Оно вообще бывает в природе? А если не бывает, то о чём тогда речь, при чём тогда wchar_t?

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

Ну, пока что с костылями и я так в Си могу:

#include <stdio.h>
#include <locale.h>
#include <wchar.h>

int
ismodifierfatc(int fatcode)
{
    if (fatcode > 0x02ff && fatcode < 0x0370)
        return 1;
    if (fatcode > 0x1aaf && fatcode < 0x1b00)
        return 1;
    if (fatcode > 0x1dbf && fatcode < 0x1e00)
        return 1;
    if (fatcode > 0x20cf && fatcode < 0x2100)
        return 1;
    if (fatcode > 0xfe1f && fatcode < 0xfe30)
        return 1;
    return 0;
}


int
main(int argc, char **argv)
{
    setlocale(LC_ALL, "");
    wchar_t* str = L"Yes 重要";
    int i, len, clen = 0;
    len = wcslen(str);
    for(i = 0; i < len; i++)
	    if (!ismodifierfatc(str[i])) clen++;
    printf("Длина строки: %d\n", clen);
    return 0;
}
$ ./wcharlentest2
Длина строки: 6
$

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

А теперь смотри как это делают в нормальных языках:

$ cat main.rs
use unicode_segmentation::UnicodeSegmentation;

fn main() {
    let one = UnicodeSegmentation::graphemes("重要", true);
    let two = UnicodeSegmentation::graphemes("👨🏿", true);

    println!("{}", one.count());
    println!("{}", two.count());
}

$ cargo run
2
1
cumvillain
()