1

Тема: Форматирование строк в CoreLite

Одним из проектов по дальнейшему развитию CoreLite является разработка собственной реализации форматирования строк:

Str.Format('Total % files, % bytes', [FileCount, TotalSize]);

Шаблоны формата будут иметь собственный синтаксис, использующий возможности открытых массивов Delphi. Странно, но ни в одном известном мне форматировщике они не используются. Открытый массив объявляется так:

procedure TWideString.Format(Fmt: PWideChar; Args: array of const);

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

Пока принят следующий синтаксис символа формата:

%[+][-][width|*][x|X|%]

Где:

  • Ширина (width) задается десятичным числом или символом *, если ширина передается в списке параметров. Лидирующий 0 задает дополнение нулями. Знак - — выравнивание по левому краю, знак + — выводить + для положительных чисел. Знаки могут идти в любом порядке. Возможна также поддержка символа ±.

  • Символы x или X задают вывод в шестнадцатиричном формате. На данный момент это единственное альтернативное представление.

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

В будущем возможно добавление индекса параметра в стеке:

%0:25

Согласно постановке, форматировщик должен форматировать числа в соответствии с локалью пользователя. Наверное, для этого придется ввести еще одно альтернативное представление, обозначаемое символом n.

Этот проект — долгострой CoreLite. В разные годы несколько раз писалась постановка, были даже попытки начать реализацию. В ветке master на GitHub модуль CoreStrings до сих пор содержит заготовку одной из реализаций. Сейчас решено сделать самый простой вариант.

Предполагается, что после реализации CoreLite перейдет на него полностью, включая исключения. Наконец-то будет решена проблема вывода знака уменьшения/приращения в PE Tool. Сейчас для вывода форматированных строк используется обертка над системной функцией wvsprintf.

Re: Форматирование строк в CoreLite

Допустим, я хочу распечатать строку с шириной 5 знаков и сразу же после этой строки напечатать цифру 0.

Если я напишу так:

Str.Format('%50', [str])

то мне сформируется строка шириной 50 знаков и без нуля на конце. Придётся делать так:

Str.Format('%5%', [str, 0])
Str.Format('%5%0', [str, ''])
Str.Format('%5%', [str, '0'])

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

А как напечатать в строке знак %? Напечатать % в формате и '%' в качестве аргумента? Тоже как-то нелогично.

Я хочу распечатать число с единицами измерения.

value := 3.7;
unit := 'cm';
s := Str.Format("%%", [value, unit])

Не напечатается ли мне '370' но без единиц измерения?

Добавлено 2020-07-19 в 19:25

Хочу написать 2+3=5:

str := Str.Format('%+%=%', [2, 3, 5]);

Знак + означает выводить «плюс» для положительных чисел. Получится строка '+23=5'.

Как предлагается решать эту проблему?

3 (изменено: Freeman, 20.07.2020 в 00:29)

Re: Форматирование строк в CoreLite

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

  • a — форматирование по умолчанию в соответствии с типом, передаваемым Delphi (a — от слова any).

  • x — вывод в шестнадцатиричном виде (по всей видимости, любых значений, в том числе адресов и буферов чисел с плавающей запятой).

  • n — вывод чисел с учетом национальных настроек.

Примеры выше:

Str.Format('%50a', [Str]);

Value := 3.7;
Unit := 'cm';
Str.Format('%a%a', [Value, Unit]); // или %n%a

Str.Format('%a+++%a=%a', [2, 3, 5]); // «плюс» придется дублировать так же, как и процент
Маздайщик пишет:
s := Str.Format("%%", [value, unit])

Не напечатается ли мне '370' но без единиц измерения?

Напечатался бы процент.

Str.Format('%a%a', [Value, Unit]);

В примере есть неоднозначность. Можно напечатать и 370%a. Нужно будет подумать над жадностью обработки процента. Или вообще выбрать другой символ формата. Знак процента — дурацкий вариант, символ вполне себе встречается в обычных текстах. Надо взять что-то чисто компьютерное или редкое, скажем ~. У нас везде Unicode, для математического «приближенно равно» есть символ .

Re: Форматирование строк в CoreLite

А зачем «плюс» дублировать? Если мы хотим вывести число со знаком, то можем написать %+a, знак «+» будет интерпретироваться как флаг только между процентом и модификатором. В остальных случаях плюс означает плюс.

5

Re: Форматирование строк в CoreLite

Маздайщик пишет:

написать %+a

Мне казалось, что запись вида %+-20a для выравнивания по левому краю выглядит странно.

Re: Форматирование строк в CoreLite

Мне кажется, при создании синтаксиса шаблона для форматирования строк нужно ориентироваться не на древнючий printf, а на форматные строки Python:

https://pythonru.com/osnovy/formatirova … hju-format

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

7

Re: Форматирование строк в CoreLite

Маздайщик пишет:

форматные строки Python

Думал об этом. Смотрел .NET, правда. Они похожи с Питоном.

Re: Форматирование строк в CoreLite

Есть и мелкие отличия в пользу Питона. Например, можно указывать выравнивание: <, =, >, соответственно, слева, посередине и справа.