Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 printf() utf8 + выравнивание по ширине  [new]
petrav
Member

Откуда:
Сообщений: 2430
Неожиданно, но по совершенно понятным причинам, перестало работать выравнивание по ширине.

    std::setlocale(LC_ALL, "");
    char str[77] = {};
    sprintf(str, "%6s", u8"ыфz");


На стековерфлоу (здесь и здесь) советуют:

- Костыли.
- Преобразовывать в utf-16.

Неужели нет нормального выхода?
21 июл 20, 10:49    [22170872]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
Basil A. Sidorov
Member

Откуда:
Сообщений: 10412
Составные символы останутся составными в любой кодировке. Следовательно, то, что вы называете костылями.
21 июл 20, 13:35    [22170998]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
petrav
Member

Откуда:
Сообщений: 2430
Basil A. Sidorov
Составные символы останутся составными в любой кодировке. Следовательно, то, что вы называете костылями.

Но если мы делаем аля setlocale("utf8"), то printf() мог бы это учитывать?

А так да -- wchar_t тут не полное решение. Нам нужно строку и формат преобразовать в UC-32, а после printf_uc32() преобразовывать обратно.
21 июл 20, 13:46    [22171015]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
rdb_dev
Member

Откуда: с болот
Сообщений: 3384
petrav, так прикрути padding пробелов ручками и обрежь через substr! Делов-то... Возможно, в printf пока что неустранённый баг, к которому надо прикрутить workaround.
21 июл 20, 13:55    [22171035]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
petrav
Member

Откуда:
Сообщений: 2430
rdb_dev
petrav, так прикрути padding пробелов ручками и обрежь через substr! Делов-то... Возможно, в printf пока что неустранённый баг, к которому надо прикрутить workaround.

sprintf("%12s %*s %16s %5s", u8"ыы", 35, u8"фф", getMyStr(), u8"яяячч");

Как вы себе представляете workaround вокруг printf()?
21 июл 20, 14:02    [22171043]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
rdb_dev
Member

Откуда: с болот
Сообщений: 3384
petrav
Как вы себе представляете workaround вокруг printf()?
А в чём проблема? Пишем функцию дополнения пробелами до нужного размера исходя из кол-ва символов, возвращающую std::string и в вызов sprintf вставляем эту функцию, в которую передаём литерал и длину поля, в которое этот литерал надо вписать, а в самом sprintf используем лишь "%s" без выкрутасов.

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

Сообщение было отредактировано: 21 июл 20, 14:12
21 июл 20, 14:11    [22171060]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
petrav
Member

Откуда:
Сообщений: 2430
rdb_dev
petrav
Как вы себе представляете workaround вокруг printf()?
А в чём проблема? Пишем функцию дополнения пробелами до нужного размера исходя из кол-ва символов, возвращающую std::string и в вызов sprintf вставляем эту функцию, в которую передаём литерал и длину поля, в которое этот литерал надо вписать, а в самом sprintf используем лишь "%s" без выкрутасов.

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

Да, действительно, можно и так. Спасибо.
21 июл 20, 14:38    [22171081]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
rdb_dev
Member

Откуда: с болот
Сообщений: 3384
petrav, попробуй так:
static const char pad_12[12] = {' '};
static const char msg[] = u8"Сообщение";
std::string temp = std::string(pad_12) + msg;
printf
  (
    "\r\n| %s |\r\n",
    temp.substr( temp.size() - (sizeof(msg) + (sizeof(pad_12) - utf8literal::length(msg))) )
  )


Сообщение было отредактировано: 21 июл 20, 14:48
21 июл 20, 14:49    [22171085]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
rdb_dev
Member

Откуда: с болот
Сообщений: 3384
Более корректный вариант:
static const char pad_12[] = "            ";
static const char msg[] = u8"Сообщение";
std::string temp = std::string(pad_12).append(msg);
printf("\r\n12345678901234567890");
size_t len = temp.size() - (sizeof(msg) - 1 + (sizeof(pad_12) - 1 - utf8literal::length(msg)));
printf
  (
    "\r\n%s\r\n",
    temp.substr(len).c_str()
  );


Сообщение было отредактировано: 21 июл 20, 15:56
21 июл 20, 15:56    [22171140]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
mayton
Member

Откуда: loopback
Сообщений: 47946
Это как в БД. Никогда наперед не знаешь сколько вернёт выборка SELECT ...

Единственный способ расчитать - это физически вычиать все записи. И посчитать уже по факту.
21 июл 20, 17:29    [22171191]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
petrav
Member

Откуда:
Сообщений: 2430
mayton
Это как в БД. Никогда наперед не знаешь сколько вернёт выборка SELECT ...

Единственный способ расчитать - это физически вычиать все записи. И посчитать уже по факту.

Нет, это как кривые руки. У printf() есть вся эта информация включая локаль. Разве я не прав?
21 июл 20, 17:37    [22171197]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 50765

petrav
Разве я не прав?

Может и прав, но толку-то с того? printf не в курсе сколько знакомест на экране займут те
байты, которые он посылает консольному драйверу.

Posted via ActualForum NNTP Server 1.5

21 июл 20, 17:42    [22171199]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
mayton
Member

Откуда: loopback
Сообщений: 47946
petrav
mayton
Это как в БД. Никогда наперед не знаешь сколько вернёт выборка SELECT ...

Единственный способ расчитать - это физически вычиать все записи. И посчитать уже по факту.

Нет, это как кривые руки. У printf() есть вся эта информация включая локаль. Разве я не прав?

Пресвятые апостолы...

Ты всё еще продолжаешь доказывать всем что строка - это массив символов?
Вечны болезни. Смерть. Налоги. И желание Петрава иметь random access ко всем буквом строк.

К слову. Ты знаешь как работает кернинг при печати True-Type?
21 июл 20, 18:14    [22171209]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
petrav
Member

Откуда:
Сообщений: 2430
mayton
petrav
пропущено...

Нет, это как кривые руки. У printf() есть вся эта информация включая локаль. Разве я не прав?

Пресвятые апостолы...

Ты всё еще продолжаешь доказывать всем что строка - это массив символов?
Вечны болезни. Смерть. Налоги. И желание Петрава иметь random access ко всем буквом строк.

Майтун, у нас проблема. В языке программирования С++ после десятков лет развития не работает базовый функционал — printf(). Юзер petrav тут вообще не при делах.

mayton
К слову. Ты знаешь как работает кернинг при печати True-Type?

Без понятия.
21 июл 20, 19:31    [22171238]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 50765

Во-первых, printf это чистый С, без плюсов.
Во-вторых, он создавался для (и рассчитан на) исключительно текстовых терминалов.
В-третьих, UTF-8 это дерьмо, широко распространившееся исключительно благодаря своей хоть
какой-то взад совместимости как раз с таким вот наследством, которое о нём вообще не в
курсе, поэтому будь благодарен, что оно хоть как-то работает, а не выводит свои
"кракозябры" в их естественном виде.

Posted via ActualForum NNTP Server 1.5

21 июл 20, 20:09    [22171250]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
petrav
Member

Откуда:
Сообщений: 2430
Dimitry Sibiryakov

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

Я считаю, что можно было сделать лучше. А utf очень плохое компромиссное решение.

И не должен я благодарить sprintf() — она не представляет ценности. Очень простая функция.

PS: Написал я костыль по мотивам совета от rdb_dev. Выравнивание заработало.
21 июл 20, 21:22    [22171286]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
mayton
Member

Откуда: loopback
Сообщений: 47946
petrav
mayton
пропущено...

Пресвятые апостолы...

Ты всё еще продолжаешь доказывать всем что строка - это массив символов?
Вечны болезни. Смерть. Налоги. И желание Петрава иметь random access ко всем буквом строк.

Майтун, у нас проблема. В языке программирования С++ после десятков лет развития не работает базовый функционал — printf(). Юзер petrav тут вообще не при делах.

У printf было много проблем. В т.ч. и по линии инфо-безопасности.
Но то о чем ты уже несколько топиков рассказываешь не является
проблемой в общем понимании этого слова.

Вообще в мире open-source принято немедленно обращяться к баг-трекеру
и заводить дефект.

Где твоё обращение? Где на него реакция? Знаешь ты можешь еще много
сотрясать воздух на sql.ru но если ты по настоящему хочешь изменений
- пиши куда надо. В комитеты. В репозитарии. В спецификации.

Если ты не знаешь как или куда. Спрашивай. Я вряд-ли подскажу т.к. я отошёл
от С++ ных дел уж лет 15 как. Но в этом форуме есть люди которые знают.
21 июл 20, 22:08    [22171310]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
mayton
Member

Откуда: loopback
Сообщений: 47946
petrav

mayton
К слову. Ты знаешь как работает кернинг при печати True-Type?

Без понятия.

Ну смотри. Чтоб расчитать длину текста в пропорциональном TrueType шрифте
есть только один способ. Его надо отпечатать. На реальном устройстве или виртуальном
не имеет значения. Кернинг - это плотное заполнение пустых протсранств между
символами или глифами символов. Например между буквами "A" и "У" будет один
кернинг а между "A" и "Ш" - другой.

Ты не можешь заранее знать длину текста в пикселах до тех пор пока его не распечатаешь.

Ты не можешь узнать количество строк в SQL выборке пока физически не сделаешь
fetch всех data-rows.

И односвязный список в функциональном программировании (очень важная и фундаментальная структура) тоже имеет неизвестную длину. Чтоб ее вычислить - нужно его перемотать
до конца. Впрочем это отдельная тема.

И пудинг нельзя оценить пока его не скушаешь.

Вобщем многое в этом мире имеет ограничения. Вот такая вот метафизика.
21 июл 20, 22:26    [22171318]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
petrav
Member

Откуда:
Сообщений: 2430
mayton
petrav
пропущено...

Майтун, у нас проблема. В языке программирования С++ после десятков лет развития не работает базовый функционал — printf(). Юзер petrav тут вообще не при делах.

У printf было много проблем. В т.ч. и по линии инфо-безопасности.
Но то о чем ты уже несколько топиков рассказываешь не является
проблемой в общем понимании этого слова.

Для людей на стек-оверфлоу это является проблемой, а для Майтуна не является. :)

mayton

Где твоё обращение? Где на него реакция? Знаешь ты можешь еще много
сотрясать воздух на sql.ru но если ты по настоящему хочешь изменений
- пиши куда надо. В комитеты. В репозитарии. В спецификации.

Отлично. Я так и сделаю. Прямо завтра напишу в комитет по С++ и в Майкрософт. Скажу что я от Майтуна пришёл.

Я задал в этом топике конкретный вопрос, получил ответ, уже реализовал в коде. И тут приходит Майтун и заявляет, что я занимаюсь чем-то не тем. Я тебе чем-то тут мешаю?
21 июл 20, 22:27    [22171319]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
mayton
Member

Откуда: loopback
Сообщений: 47946
Вот ты чудак. Тыж сам мне пишешь.

В языке дескать проблема. Не?
21 июл 20, 23:04    [22171331]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 50765

petrav
Я задал в этом топике конкретный вопрос, получил ответ, уже реализовал в коде.

Угу. Реализовал конкретную затычку для конкретного случая. Теперь добавь в свою строку
пару суррогатов и ESC-последовательность чтобы оценить тщету всего сущего.

Posted via ActualForum NNTP Server 1.5

22 июл 20, 00:25    [22171352]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
petrav
Member

Откуда:
Сообщений: 2430
Dimitry Sibiryakov

petrav
Я задал в этом топике конкретный вопрос, получил ответ, уже реализовал в коде.

Угу. Реализовал конкретную затычку для конкретного случая. Теперь добавь в свою строку
пару суррогатов и ESC-последовательность чтобы оценить тщету всего сущего.

Да я понимаю, что решение не совершенно. Пока оно устраивает. Тратить время на изучение ICU я пока не готов.
22 июл 20, 00:30    [22171353]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
Basil A. Sidorov
Member

Откуда:
Сообщений: 10412
Dimitry Sibiryakov
Теперь добавь в свою строку пару суррогатов
Суррогаты нужны только для UTF-16. "Well formed" UTF-8/-32 не должны содержать суррогатов (даже в парах).
и ESC-последовательность чтобы оценить тщету всего сущего.
Надеюсь, UTF-8 не будет обременён "грехами" ANSI-терминала?
22 июл 20, 03:00    [22171370]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 50765

Basil A. Sidorov
Надеюсь, UTF-8 не будет обременён "грехами" ANSI-терминала?

А куда он денется? Другого-то способа вывода в Си нет.

Posted via ActualForum NNTP Server 1.5

22 июл 20, 12:44    [22171634]     Ответить | Цитировать Сообщить модератору
 Re: printf() utf8 + выравнивание по ширине  [new]
Barlone
Member

Откуда:
Сообщений: 1401
petrav
mayton
пропущено...

У printf было много проблем. В т.ч. и по линии инфо-безопасности.
Но то о чем ты уже несколько топиков рассказываешь не является
проблемой в общем понимании этого слова.

Для людей на стек-оверфлоу это является проблемой, а для Майтуна не является. :)

mayton

Где твоё обращение? Где на него реакция? Знаешь ты можешь еще много
сотрясать воздух на sql.ru но если ты по настоящему хочешь изменений
- пиши куда надо. В комитеты. В репозитарии. В спецификации.

Отлично. Я так и сделаю. Прямо завтра напишу в комитет по С++ и в Майкрософт. Скажу что я от Майтуна пришёл.

Я задал в этом топике конкретный вопрос, получил ответ, уже реализовал в коде. И тут приходит Майтун и заявляет, что я занимаюсь чем-то не тем. Я тебе чем-то тут мешаю?
Не будет изменений в sprintf. В формате кроме минимальной ширины можно задать и максимальную. Если минимальная ширина будет учитывать количество символов, а максимальная - количество байт, то это будет нелогично. Я если максимальную тоже сделать количеством символов, это сломает программы, которые используют максимальную ширину для защиты от переполнения буфера.
22 июл 20, 13:56    [22171686]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / C++ Ответить