powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вычисление длины utf-8 строки в compile time
25 сообщений из 76, страница 1 из 4
Вычисление длины utf-8 строки в compile time
    #39982007
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как думаете нормально? Работать будет? :)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
inline constexpr
size_t c_strlen(char const *start, size_t const maxBuffSize)
{
    char const *end = start;
    while (*end != '\0')
    {
        ++end;

        if (end - start >= maxBuffSize)
        {
            throw std::runtime_error("The string is too long.");
        }
    }

    size_t charCount = 0;
    while (start < end)
    {
        byte const ch = static_cast<byte>(*start);
        size_t chSize = {};

        if      ((ch & 0x80) == 0x00)   chSize = 1;
        else if ((ch & 0xE0) == 0xC0)   chSize = 2;
        else if ((ch & 0xF0) == 0xE0)   chSize = 3;
        else if ((ch & 0xF8) == 0xF0)   chSize = 4;
        else throw std::runtime_error("Invalid UTF-8 char.");

        if (chSize > end - start)
        {
            throw std::runtime_error("UTF-8 string too short.");
        }

        for (size_t i = 1; i < chSize; ++i)
        {
            if ((start[i] & 0xC0) != 0x80)
            {
                throw std::runtime_error("Expected continuation UTF-8 byte.");
            }
        }

        ++charCount;
        start += chSize;
    }

    return charCount;
}
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982150
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav, так ты скомпилируй и посмотри! :)
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982160
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav, к чему вообще весь этот зоопарк, если тебе, всего лишь, надо узнать кол-во байт литерала?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
#include <cstdlib>
#include <stdio.h>

using namespace std;

static constexpr char test[] = u8"Тестовое сообщение";

int main(int argc, char** argv)
{
  printf("\r\n%zu\r\n", sizeof(test));
  return 0;
}

Результат, как и ожидалось, "36".
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982176
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
petrav, к чему вообще весь этот зоопарк, если тебе, всего лишь, надо узнать кол-во байт литерала?

Не количество байт, а количество символов. И не обязательно у литерала. Compile time только по возможности.

Я, конечно, тестировал на русских буквах и иероглифах. Но я ведь программировал по мотивам кода со стек-оферфлоу. И там было приписано, что реализация наивная. Поэтому и спрашиваю, может можно улучшить.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982185
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я когда-то взял не глядя функцию UTF2Unicode с хабра https://habr.com/ru/post/282191/
Правда параметр заменил на
Код: plaintext
1.
const /*unsigned*/ char* txt


Для подсчета символов тоже подойдет. На иероглифах не пробовал.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982200
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad,
А какой смысл в символах считать? Это не универсально.
Может на знаки? Диакритические знаки? Кодовые точки, составные символы?
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982204
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,
Вот как-то так...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
#include <cstdlib>
#include <stdio.h>

using namespace std;


static constexpr char test[] = u8"Тестовое сообщение";

class utf8literal
{
  template <typename T>
  static constexpr
  size_t bytes_per_u8char(T chr, bool start = true)
  {
    return (start && !(chr & 0x80))
        ? 1
        : (chr & 0x80)
            ? 1 + bytes_per_u8char(chr << 1, false)
            : 0;
  }

  template <typename T, size_t D>
  static constexpr
  size_t calc_length(T (&a)[D], size_t i = 0)
  {
    return (i < D)
        ? 1 + calc_length(a, i + bytes_per_u8char(a[i]))
        : 0;
  }

public:

  template <typename T, size_t D>
  static constexpr
  size_t length(T (&a)[D])
  {
    return calc_length<T, D>(a) - 1;
  }
};

int main(int argc, char** argv)
{
  printf("\r\n%zu\r\n", utf8literal::length(test));
  return 0;
}

Только не забудь впихнуть static_assert для (T != char).
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982205
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
А какой смысл в символах считать? Это не универсально.
Может на знаки? Диакритические знаки? Кодовые точки, составные символы?
Лично мне эта функция нужна для целей, описанных в статье - для рендеринга. И длину я считаю не в символах, в пикселях. Но алгоритм можно заюзать и для подсчета символов, например, для выравнивания вывода моноширинного шрифта в консоли.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982206
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
petrav,
Вот как-то так...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
#include <cstdlib>
#include <stdio.h>

using namespace std;


static constexpr char test[] = u8"Тестовое сообщение";

class utf8literal
{
  template <typename T>
  static constexpr
  size_t bytes_per_u8char(T chr, bool start = true)
  {
    return (start && !(chr & 0x80))
        ? 1
        : (chr & 0x80)
            ? 1 + bytes_per_u8char(chr << 1, false)
            : 0;
  }

  template <typename T, size_t D>
  static constexpr
  size_t calc_length(T (&a)[D], size_t i = 0)
  {
    return (i < D)
        ? 1 + calc_length(a, i + bytes_per_u8char(a[i]))
        : 0;
  }

public:

  template <typename T, size_t D>
  static constexpr
  size_t length(T (&a)[D])
  {
    return calc_length<T, D>(a) - 1;
  }
};

int main(int argc, char** argv)
{
  printf("\r\n%zu\r\n", utf8literal::length(test));
  return 0;
}

Только не забудь впихнуть static_assert для (T != char).

Как-то у вас всё переусложнено, ИМХО. Я так понимаю тут подсчитываются лидирующие символы, а не лидирующие пропускаются.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982217
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Как-то у вас всё переусложнено, ИМХО.
Наоборот - всё до безобразия упрощено.

petrav
Я так понимаю тут подсчитываются лидирующие символы, а не лидирующие пропускаются.
Пропуск кол-ва байт символа определяется по старшим битам лидирующего байта символа, а в подсчёт попадают именно символы. Попробуй впихнуть в литерал между русскими символами те, что кодируются четырьмя байтами и почувствуй разницу. Ведь ты же хотел именно подсчёт символов, а не байт?
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982219
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad,
В пикселях же в winApi есть?
Типа getTextPoint.....
И там учитывается шрифт, выравнивание и куча всего.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982225
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
В пикселях же в winApi есть?
Может быть и есть, но winApi нет на ведроиде и яблоке.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982226
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
petrav
Как-то у вас всё переусложнено, ИМХО.
Наоборот - всё до безобразия упрощено.

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

Да символов. Попробовал, с моим кодом тоже всё работает.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982239
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav, enjoy! :)
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982240
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
petrav, enjoy! :)

Правда у меня смесь русских букв и иероглифов (иероглифы в три байта).
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982241
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Правда у меня смесь русских букв и иероглифов (иероглифы в три байта).
Для теста самое то!
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982253
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad
PetroNotC Sharp
В пикселях же в winApi есть?
Может быть и есть, но winApi нет на ведроиде и яблоке.

Блин, опять универсальность везде).
Тогда конечно.
А так там свои API есть
Типа:
getTextBounds
Added in API level 1
public void getTextBounds (String text,
int start,
int end,
Rect bounds)
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982270
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp,

Я стараюсь все, что можно сделать на перенесимом C++, делать на нем. Посчитать размер выводимой через openglES строки текста - задача не сложная. Завязываться на специфичное Java-API ради этого не хочется.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982272
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Осталась сущая мелочь: найти в С++ переносимые шрифты.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982279
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad,

У OpenGL разве не в Canvas. У которого есть Pаint. С длиной текста методом?
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982281
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Осталась сущая мелочь: найти в С++ переносимые шрифты.
Статья как раз о том, как сделать такой "шрифт" на основе SDF.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982284
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad
Dimitry Sibiryakov

Осталась сущая мелочь: найти в С++ переносимые шрифты.
Статья как раз о том, как сделать такой "шрифт" на основе SDF.
и отрисовать попиксельно сглаживая) :))
Круто.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982285
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Глянул статью - опять игрушки.
Понятно.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982287
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
AmKad,

У OpenGL разве не в Canvas. У которого есть Pаint. С длиной текста методом?
Не знаю что такое canvas и paint. У openGL(ES) нет функций для вывода текста. Только многоугольники. В случае ES - треугольники. Вообще, если интересно покопаться в моем говнокоде и закидать меня помидорами, могу дать ссылку на репозиторий.
...
Рейтинг: 0 / 0
Вычисление длины utf-8 строки в compile time
    #39982288
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
Глянул статью - опять игрушки.
Понятно.
Да. Увы, на что-то серьезное я не способен
...
Рейтинг: 0 / 0
25 сообщений из 76, страница 1 из 4
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вычисление длины utf-8 строки в compile time
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]