Format — Функция Delphi


Format — Функция Delphi

width] [.precision] type
index -это индекс в массиве Args, где первый аргумент обозначается нулем. Без указания индекса каждый спецификатор формата соответствует следующему элементу массива Args. Если указан индекс, можно несколько раз повторять один и тот же аргумент в одной строке формата. Планируя локализовать приложение, следует использовать спецификатор индекса для всех аргументов, т. к. в другом языке может потребоваться другой порядок аргументов.
width определяет минимальное количество символов для форматируемого поля. Если фактическая форматируемая величина меньше, чем width символов, она дополняется пробелами слева. Если перед width указан знак «минус», число выравнивается слева и дополняется пробелами справа.
Разные типы форматов по-разному используют precision. Подробности рассмотрены в описаниях каждого из форматов.
Можно жестко указать числовые значения index, width и precision в строке формата (например %1:10.2f) или использовать звездочку для любого или всех этих значений (например %*:*. * f). Тогда для данного значения будет использован следующий аргумент из массива Args. Значение Args должно быть целым.
Тип формата (type) обозначается одним символом в верхнем или нижнем регистре:
d
Форматирует десятичное целое со знаком. Precision определяет минимальное число выводимых цифр; по необходимости число дополняется нулями. Значение Args должно быть целым.
е Форматирует вещественное число в соответствии с экспоненциальной нотацией. Precision определяет общее число цифр в форматированной строке. По умолчанию равно 15. Значение Args должно быть числом с плавающей точкой или Currency.
f
Форматирует вещественное число в соответствии с фиксированной нотацией. Precision определяет количество цифр после десятичного разделителя. По умолчанию равно 2. Значение Args должно быть числом с плавающей точкой или Currency.
g
Форматирует вещественное число в соответствии с общей нотацией. Precision определяет количество значащих цифр. Значение Args должно быть числом с плавающей точкой или Currency.
m
Форматирует значение типа Currency. Precision определяет количество знаков после десятичной точки. Значение по умолчанию определяется переменной CurrencyDecimals, а формат валюты-переменными CurrencyFornat и NegCurrFormat. Значение Args должно быть числом с плавающей точкой или Currency.
n
Форматирует вещественное число в соответствии с числовой нотацией, т. е. по правилам фиксированной нотации с разделителем ThousandSeparator для групп из трех цифр. Значение Args должно быть числом с плавающей точкой или Currency.
р
Форматирует указатель как шестнадцатеричное число. Значение Args должно быть указателем.
s
Форматирует символ или строку. Precision определяет максимальное число выводимых символов. Значение Args должно иметь тип AnsiChar, AnsiString, PChar, PWideChar, ShortString, Variant или WideStririg. Тип WideChar не допускается. Variant преобразуется в строку и затем форматируется.
u
Форматирует целое десятичное число без знака. Precision определяет минимальное число выводимых десятичных цифр; число дополняется по необходимости нулями. Значение Args должно быть целым.
х
Форматирует шестнадцатеричное целое без знака. Регистр спецификатора типа определяет регистр символов шестнадцате-ричного числа. Precision определяет минимальное число выводимых цифр, при необходимости дополняется нулями. Значение Args должно быть целым.
Если строка формата содержит ошибки или если type не совпадает с типом соответствующего аргумента массива Args, Format генерирует исключительную ситуацию EConvertError.

Format — Функция Delphi

В языке C++ есть много всяких форматирующих функций. Например: printf, sprintf и т.д. Когда их вызываешь, то кол-во параметров неограниченно, например:

char name[255];
DWORD age;
char addr[255];

printf(«\n Name: %s\n Age: %d\n Address: %s\n», name, age, addr);

Можно ли сделать какую-нибудь подобную функцию для Delphi.

И в дельфи есть и тоже крличество параметров неограничено, а то что привел это почти полный аналог под названием format

В Delphi есть функция

format(«ляляля %s нет нет нет %d»,[«оппа»,10]).

Сори, дублировал ответ

Я не хочу использовать SysUtils, а об этой функции я сам знаю.

Читайте внимательно вопрос: Можно ли сделать какую-нибудь подобную функцию для Delphi(функцию printf с неограниченным кол-вом параметров — в функции format массив,а не неограниченное число параметров).

а чем так принципиально отличается форма записи Func(a, [b, c, d, . ]) от Func(a, b, c, d, . ) ? парой лишних скобок? ну нельзя сделать без скобок, нельзя. только со скобками. теперь вы удовлетворены? %-)

Satanas Nobiscum! 09-Nov-XXXVII A.S.

А может, тогда лучше использовать API-функции wvsprintf и wsprintf? Вполне :)
Или — динамические массивы указателей на разнотипные параметры.

2Ketmar: Хорошо. Как можно?

Внук: Да, но только есть одна загвоздка.

function i2s(value : dword) : string;
const format : pchar = «%d»;
var buffer : pchar;
begin
getmem(buffer, 256);
asm
push value
push format
push buffer
call wsprintf
add esp, 0Ch
end;
result := string(buffer);
freemem(buffer);
end;

Эта функция аналог IntToStr. Здесь сразу известно кол-во параметров для форматирования (1) и сама строка («%d»). А что делать когда оно не известно? Пользователь мог отформатировать («name: %s», name) , а мог и («name: %s age: %d», name, age) . Как быть?

а можно так, как в Format сделано. цитата из хэлпа:
function MakeStr(const Args: array of const): string;

const
BoolChars: array[Boolean] of Char = («F», «T»);
var
I: Integer;
begin
Result := «»;
for I := 0 to High(Args) do
with Args[I] do
case VType of
vtInteger: Result := Result + IntToStr(VInteger);
vtBoolean: Result := Result + BoolChars[VBoolean];
vtChar: Result := Result + VChar;
vtExtended: Result := Result + FloatToStr(VExtended^);

vtString: Result := Result + VString^;
vtPChar: Result := Result + VPChar;
vtObject: Result := Result + VObject.ClassName;
vt >vtAnsiString: Result := Result + string(VAnsiString);
vtCurrency: Result := Result + CurrToStr(VCurrency^);
vtVariant: Result := Result + string(VVariant^);
vtInt64: Result := Result + IntToStr(VInt64^);

MakeStr([«test», 100, » «, True, 3.14159, TForm])
returns the string “test100 T3.14159TForm”.

Satanas Nobiscum! 09-Nov-XXXVII A.S.

V Pascal»e i v C raznye soglasheniya vyzova. No v principe, dynamicheskij massiv kak parameter ochen» malo otlyuchaetsya ot peremennogo chisla parametrov (i tam, i tam peredayetsya chislo parametrov, a potom samy parametry).

Использовал дин. массив, только ошибка вылезает, помогите.

function format(value : string; const args : array of const) : string;
var
format : pchar;
buffer : pchar;
c : dword;
begin
result := «»;
format := «»;
buffer := «»;
c := 0;

while pos(«%», value) <> 0 do
begin
result := result + copy(value, 1, pos(«%», value) — 1);
format := pchar(copy(value, pos(«%», value), 2));
delete(value, 1, pos(«%», value) + 1);

getmem(buffer, 256);
asm
push args[c]
push format
push buffer
call wsprintf
add esp, 0Ch
end;
result := result + string(buffer);
freemem(buffer);
inc(c);
end;
end;

Ошибка из-за push args[c], наверно. А как бороться — НЕ ЗНАЮ!

Chto est» wsprintf? Vy uvereny, chto ej imenno takie parametry nuzhny?

Net proverki na c

Пример на wvsprintf тут http://delphibase.endimus.com/?action=viewtopic&topic=strchange :))

Alex44 -> Стандартный format из SysUtils, который я не использую.

Внук -> Я посмотрел. Попробую разобраться. Главное — чтобы @args в третьем параметре работало! (const args : array of const)

Василий2 © (11.11.02 12:59)

А SysUtils не используется по религиозным соображениям ? Или из духа Ивана Кулибина, который является по ночам и шепчет: «Изобретай велосипед, сынку, и будет тебе почет и уважение».

2Игорь Шевченко:
а SysUtils большой. а вырезать функцию Format запрещает этика и эстетика (некрасиво файлы на куски резать! %-).

Satanas Nobiscum! 11-Nov-XXXVII A.S.

Ketmar © (11.11.02 14:17)

Василий2 © (11.11.02 14:35)

А если идет борьба за уменьшение размеров, то имеет смысл обратиться в сторону программ на языке ассемблера — там не только SysUtils, а даже system не используется — экономия поразительная. Можно из одного байта работающую программу написать.

2Игорь Шевченко:
вот и я говорю: некрасиво. видите, как мы сошлись во мнении?

Satanas Nobiscum! 11-Nov-XXXVII A.S.

вот аналог от Format(SysUtils) на читом api, кому надо

function Format(const Format: string; const Args: array of const): string;
type
array_of_pointer = array[0..0]of pointer;
var
n: integer;
ap: ^array_of_pointer;
buf: array[0..1023]of char;
begin

result:= «»;
n:= length(Args);
if (n = 0) then exit;

getmem(ap, n * sizeof(Pointer));

for n:= 0 to (n-1) do
ap[n]:= Args[n].VPointer;

try
n:= wvsprintf(buf, @Format[1], PChar(@ap[0]));
SetString(Result, buf, n);
except
end;
freemem(ap);
end;

Давить надо за такой стиль

так лучше, или чего тебе герою непонравилось?

try
n:= wvsprintf(buf, @Format[1], PChar(@ap[0]));
SetString(Result, buf, n);
except
result:= «»;
end;

Eugen Honeker -> Спасибо за попытку помочь, но почему-то когда я вызываю эту функцию, она форматированные данные не выводит. Например: writeln(format(«Program: %s.», [«MyProg»])); В консоли написано: «Program .»

Ой, извиняюсь. Не

writeln(format(«Program: %s.», [«MyProg»])); , а

writeln(format(«Param1: %s.», [ParamStr(1)]));

В строке написано: «Param1: .»

А как вызывал программу, для начала проверь ParamStr(0)]));

Еще вопросик: А почему форматируются только 2 параметра, хотя я указывал 3?

что то у тебя проблемы с параметрами.
вот тебе пример

const
fmt = «%s %s %s %s [0x%.08x] %c»;
.
MessageBox(0, @Format(fmt, [«ich»,»bin»,»ein»,»lammer», 43962, «.»])[1], nil, 144);

выдаёт на экране:

ich bin ein lammer [0x0000abba] .

Функции форматирования

Function FloatToStrF(Value: Extended; Format: TFloatFormat; Precision, Digits: Integer): String;

Преобразовывает число с плавающей запятой, в строковое представление.

Параметр Format определяет формат результирующей строки.

Параметр Precision определяет точность данного значения. Он должен быть равен 7 или меньше для значений типа Single, 15 или меньше для значений типа Double и 18 или меньше для значений типа Extended.

Значение параметра Digit зависит от выбранного формата.

Возможные значения параметра Format описаны ниже.

  • ffGeneral — общий формат числа. Значение преобразовывается в самую короткую возможную десятичную строку, использующую фиксированный или научный формат. Конечные нули удаляются, а десятичная точка появляется только в случае необходимости. Параметр Digit определяет минимальное число цифр в порядке числа (между 0 и 4).
  • ffExponent — научный формат. Значение преобразовывается в строку вида «-d. ddd . E + dddd». Общее количество цифр в результирующей строке (включая одну перед десятичной точкой) определяется параметром Precision. Параметр Digit определяет минимальное число цифр в порядке числа (между 0 и 4).
  • ffFixed — фиксированный формат. Значение преобразовывается в строку вида «-ddd. ddd . «. Число цифр после десятичной точки определяется параметром Digit и должно быть не больше 18. Если число цифр слева от десятичной точки больше, чем определено в параметре Precision, используется научный формат.
  • ffNumber — числовой формат. Значение преобразовывается в строку вида «-d, ddd, ddd.ddd . «. Формат ffNumber соответствует формату ffFixed, за исключением того, что возникающая в результате строка содержит разделитель тысяч.
  • ffCurrency — денежный формат. Значение преобразовывается в строку, которая представляет собой денежную величину. Преобразование управляется глобальными переменными CurrencyString, CurrencyFormat, NegCurrFormat, ThousandSeparator и DecimalSeparator, которые определяются соответствующими значениями раздела «Язык и стандарты» Панели управления Windows. Число цифр после десятичной точки определяется параметром Digits и должно быть не больше 18.
Илон Маск рекомендует:  SeekEof - Функция Delphi

Если параметр Value принимает бесконечное значение (с плюсом или минусом), функция возвращает соответственно «INF» или «-INF».

Function StrToFloat(const S: String): Extended;

Преобразовывает данную строку в число с плавающей запятой. Строка должна состоять из необязательного знака (+ или -), последовательности цифр с необязательной десятичной точкой и необязательным «E» или «e», сопровождаемым целым числом со знаком.

Глобальная переменная DecimalSeparator определяет символ, который будет использоваться как десятичная точка. Разделитель тысяч и обозначения денежной единицы не допускаются. Если строка имеет неверный формат, возбуждается исключительная ситуация EConvertError.

Function IntToStr(Value: Integer): String;

Преобразовывает целое число в строку.

Function StrToInt(const S: String): Integer;

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

Format — Функция Delphi

Пишу под Linux на KDevelop

Нужна функция типа format в Delphi/Builder, чтобы возвращала строку

есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),
а нужно чтобы вернула результирующую строку,
можно написать обертку, для sprintf, но я не очень разбираюсь с функциями с неопределенным количеством параметров

От: ZegSoft
Дата: 12.09.11 13:08
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>Пишу под Linux на KDevelop

MAS>Нужна функция типа format в Delphi/Builder, чтобы возвращала строку

MAS>есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),
MAS>а нужно чтобы вернула результирующую строку,
MAS>можно написать обертку, для sprintf, но я не очень разбираюсь с функциями с неопределенным количеством параметров

MAS>вопчем ПАМАГИТЕ

А почему тема Delphi/Builder в ветке C/C++.

От: MASReady
Дата: 12.09.11 13:13
Оценка:

ZS>А почему тема Delphi/Builder в ветке C/C++.

потому что MAS>>Пишу на c/c++ под Linux на KDevelop
читаем вопрос внимательней

От: ДимДимыч http://klug.org.ua
Дата: 12.09.11 13:38
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),

От: MASReady
Дата: 12.09.11 14:25
Оценка:

Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, MASReady, Вы писали:

MAS>>есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),

ДД>есть vsprintf().

vsprintf тоже int возвращает, а не строку
int vsprintf (char * str, const char * format, va_list arg );

От: uzhas
Дата: 12.09.11 14:46
Оценка: +1
От: MASReady
Дата: 12.09.11 15:03
Оценка:

можно сделать при помощи boost::format, QString и иже с ними, но это сильно все усложняет

нужна простая C-шная реализация

От: ДимДимыч http://klug.org.ua
Дата: 12.09.11 15:11
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>vsprintf тоже int возвращает, а не строку
MAS>int vsprintf (char * str, const char * format, va_list arg );

Строку он кладет в char * str. Поэтому, кстати, настоятельно рекомендуется использовать vsnprintf(), чтобы не произошло переполнения буфера.
В GNU C library есть еще vasprintf(), которая сама распределяет память для строки.

От: Ops
Дата: 12.09.11 15:43
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>Пишу под Linux на KDevelop

MAS>Нужна функция типа format в Delphi/Builder, чтобы возвращала строку

MAS>есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),
MAS>а нужно чтобы вернула результирующую строку,
MAS>можно написать обертку, для sprintf, но я не очень разбираюсь с функциями с неопределенным количеством параметров

MAS>вопчем ПАМАГИТЕ

А обязательно нужна функция, и именно C-style?
Потому что можно например так: http://www.rsdn.ru/forum/cpp/4074684.1.aspx

От: SaZ
Дата: 12.09.11 15:51
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>можно сделать при помощи boost::format, QString и иже с ними, но это сильно все усложняет

MAS>нужна простая C-шная реализация

Настоятельно рекомендую так не делать. Перед употреблением познакомиться с возможными последствиями возврата указателей на локальные переменные.

От: MASReady
Дата: 12.09.11 18:55
Оценка:

Здравствуйте, SaZ, Вы писали:

SaZ>Настоятельно рекомендую так не делать. Перед употреблением познакомиться с возможными последствиями возврата указателей на локальные переменные.

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

От: MASReady
Дата: 13.09.11 09:04
Оценка:

Здравствуйте, SaZ, Вы писали:

SaZ>Здравствуйте, MASReady, Вы писали:

MAS>>можно сделать при помощи boost::format, QString и иже с ними, но это сильно все усложняет

MAS>>нужна простая C-шная реализация

SaZ>Настоятельно рекомендую так не делать. Перед употреблением познакомиться с возможными последствиями возврата указателей на локальные переменные.

SaZ>

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

От: SaZ
Дата: 13.09.11 09:57
Оценка: +1

Здравствуйте, MASReady, Вы писали:

MAS>почитал про возврат ссылок (или указателей) на локальные переменные
MAS>но у тебя в коде my_vsnprintf возвращается ссылка не на локальную переменнную, а на полученную во входных параметрах, где здесь может быть проблема?

Я так написал, чтобы не говнокодить писать неудобный код. Вообще, как писали ранее, vsnprintf должна полностью делать то, что тебе нужно. А ещё лучше использовать std::string и прочие, чтобы не городить велосипедов.

От: Michael7
Дата: 13.09.11 20:02
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>Спасибо брат, я как раз подбирался к этому, но не успел
MAS>Скажи где познакомиться с возможными последствиями возврата указателей на локальные переменные.
MAS>Переменная будет скопирована и уничтожена сразу после возвращения, какой может быть здесь криминал?

Локальные переменные выделяются на стеке и после выхода из функции или метода класса там может даже что-то другое оказаться. Особенно, если по дороге где-то неявно еще были вызовы функций (умные указатели, перегруженные операторы и т.п.)

В принципе можно даже segfault словить.

От: dmitryalexeeff
Дата: 14.09.11 02:08
Оценка: 1 (1) -1


1. Если уж пишешь на C, то нужно понимать его . суть. А суть такая что это почти ассемблер по своей идеологии. А так как всем охота иметь строки произвольной длинны, и ни один нормальный человек не будет передавать через стек (а именно через стек и возвращаются все результаты работы функций) кусок данных потенциально бесконечного размера, ну или просто достаточно крупного размера. Поэтому в C, функции не возвращают строки! На крайняк они возвращают УКАЗАТЕЛИ на строки. ( char и char* это как-бе разные вещи )
2. А как-же работают все строковые функции? Есть два метода, либо они сами выделяют память, шаманят в ней, а потом возвращают указатель char* на выделенный блок ( но это как-бе нестандартный для C подход ). Второй метод подразумевает что вы САМИ выделили кусок динамической памяти для строки, запомнили адрес этого куска в типизированном указателе char* ( то есть типа строку создали ) и передаёте этот указатель в строковую функцию, которая через указатель лезет в выделенный вами блок памяти и делает с ним разные интимные вещи.

То есть, если говорить о способах реализации и использования строковых функций в C, то :
А. Есть общепринятый велосипед с передачей в функцию указателя на уже инициализированную строку
Б. Есть другие велосипеды, реже используемые, с квадратными колёсами, но работоспособные

P.S. И да, в C++ можно возвращать из функции строки, не парясь с выделением памяти и указателями. Эти возможности реализуются либо стандартной библиотекой языка C++, либо сторонними библиотеками, из которых я могу назвать Qt, boost
P.P.S. И да, C и C++ это разные языки

От: MASReady
Дата: 19.09.11 13:57
Оценка:

Здравствуйте, dmitryalexeeff, Вы писали:

D>1. Если уж пишешь на C, то нужно понимать его . суть. А суть такая что это почти ассемблер по своей идеологии. А так как всем охота иметь строки произвольной длинны, и ни один нормальный человек не будет передавать через стек (а именно через стек и возвращаются все результаты работы функций) кусок данных потенциально бесконечного размера, ну или просто достаточно крупного размера. Поэтому в C, функции не возвращают строки! На крайняк они возвращают УКАЗАТЕЛИ на строки. ( char и char* это как-бе разные вещи )
D>2. А как-же работают все строковые функции? Есть два метода, либо они сами выделяют память, шаманят в ней, а потом возвращают указатель char* на выделенный блок ( но это как-бе нестандартный для C подход ). Второй метод подразумевает что вы САМИ выделили кусок динамической памяти для строки, запомнили адрес этого куска в типизированном указателе char* ( то есть типа строку создали ) и передаёте этот указатель в строковую функцию, которая через указатель лезет в выделенный вами блок памяти и делает с ним разные интимные вещи.

D>То есть, если говорить о способах реализации и использования строковых функций в C, то :
D>А. Есть общепринятый велосипед с передачей в функцию указателя на уже инициализированную строку
D>Б. Есть другие велосипеды, реже используемые, с квадратными колёсами, но работоспособные

D>P.S. И да, в C++ можно возвращать из функции строки, не парясь с выделением памяти и указателями. Эти возможности реализуются либо стандартной библиотекой языка C++, либо сторонними библиотеками, из которых я могу назвать Qt, boost
D>P.P.S. И да, C и C++ это разные языки

это все понятно,

От: SaZ
Дата: 19.09.11 15:01
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>это все понятно,

MAS>я про то что:
MAS>

Это всё страшное извращение, чреватое кучей ошибок). Зачем это нужно? Как тут уже выше давали ссылку, вот нормальный подход

От: dmitryalexeeff
Дата: 20.09.11 00:46
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>

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

От: MASReady
Дата: 27.10.11 06:09
Оценка:

Вот что получилось в итоге, мож кому пригодится, главное не забыть когда строка станет ненужной сделать ей free
может и не супер стильно зато стабильно и удобно.

Format — Функция Delphi

Описание
Функция форматирует элементы открытого массива Args в соответствии со строкой форматирования Format. В качестве результата функция возвращает отформатированную строку.
Информацию о строках формата см. в Приложении «Строки форматирования».

При форматировании строк с помощью функций Format, FormatBuf, StrFmt, StrLFmt, процедуры FmtStr, в качестве одного из параметров, в данных подпрограммах используется строка форматирования. Строка форматирования может содержать в себе два типа объектов — обычные символы и спецификаторы (команды форматирования). Обычные символы копируются один к одному в результирующую строку. Спецификаторы применяются для выборочного форматирования элементов из списка аргументов.

Общий вид спецификатора можно представить в следующем виде:

«%» [index «:»] [«-«] [width] [«.» prec] type

Спецификатор начинается с символа %. За ним следуют:

Необязательный параметр [index «:»], задающий индекс аргумента.
Индикатор выравнивания по левому краю [«-«] (необязательный параметр).
Необязательный параметр [width], задающий минимальную длину результирующей строки.
Необязательный параметр [«.» prec], задающий точность.
Символ преобразования типа, type.

Илон Маск рекомендует:  Атрибут wrap в HTML

Идентификатор type может иметь одно из значений представленных в таблице:

d Десятичный формат. Аргумент должен иметь целочисленное значение, которое будет преобразовано в строку символов десятичных цифр. Если строка форматирования содержит спецификатор точности prec, то результирующая строка должна содержать, как минимум, указанное в спецификаторе количество цифр. Если аргумент содержит меньшее количество цифр, то в результирующую строку перед значением числа будут добавлены нули.
u Десятичный беззнаковый формат. Форматируется аналогично параметру d, но знак числа не выводится.
e Научный формат. Аргумент должен представлять собой число с плавающей запятой. Значение будет преобразовано в строку формата «-d.ddd. E+ddd». Результирующая строка начинается со знака минус, если значение аргумента отрицательно. Десятичной точке всегда предшествует одна цифра. Общее количество цифр, включая стоящую перед десятичной точкой, задается спецификатором точности. Если спецификатор точности отсутствует, то используется значение по умолчанию — 15 цифр. После символа экспоненты всегда стоит знак плюс или минус и как минимум трехразрядное число.
f Фиксированный формат. Аргумент должен быть числом с фиксированной десятичной точкой. Значение аргумента будет преобразовано в строку формата «-ddd.ddd. «. Результирующая строка начинается со знака минус, если аргумент отрицателен. Количество десятичных знаков после разделителя определяется спецификатором точности prec. Если спецификатор точности отсутствует, то после десятичной точки выводятся заданные по умолчанию 2 десятичных знака.
g Общий формат. Аргумент должен быть числом с плавающей запятой. Значение аргумента преобразовывается в наиболее возможно короткую строку, используя фиксированный или научный формат. Количество значащих цифр в результирующей строке задается спецификатором точности prec. При отсутствии данного параметра выводится по умолчанию 15 знаков. Нули в конце строки не выводятся, Десятичный разделитель ставится только в случае необходимости. Фиксированный формат используется, если количество значащих цифр до десятичной точки меньше или равно значению указанному в спецификаторе точности, и если значение аргумента больше или равно 0.00001. В других случаях в результирующей строке используется научный формат.
n Числовой формат. Аргумент должен быть числом с плавающей запятой. Результирующая строка имеет вид «-d,ddd,ddd.ddd. «. Данный формат аналогичен фиксированному формату. Отличие состоит в том, что результирующая строка включает в себя разделители тысяч.
m Денежный формат. Аргумент должен быть числом с плавающей запятой. Значение аргумента преобразовывается в строку, содержащую символ, денежной единицы. Преобразование производится в соответствии со значениями глобальных переменных CurrencyString, CurrencyFormat, CurrencyDecimals, NegCurrFormat, ThousandSeparator, DecimalSeparator. Если строка формата содержит спецификатор точности prec, то значение глобальной переменной CurrencyDecimals игнорируется.
p Указатель. Аргумент должен быть указателем (тип Pointer). Значение аргумента преобразовывается в строку из 8-ми символов формата ХХХХYYYY, где ХХХХ — адрес сегмента, а YYYY — смещение в шестнадцатеричной форме.
s Строковый формат. Аргумент должен представлять собою символ, строку типа string или PChar. Значение аргумента вставляется на место спецификатора. Длина результирующей строки задается спецификатором точности prec. Если длина исходной строки превышает значение спецификатора точности, то она усекается.
x Шестнадцатеричный формат. Аргумент должен иметь целочисленное значение. Значение аргумента преобразовывается в строку шестнадцатеричных чисел. Спецификатором точности prec, задает минимальное количество символов результирующей строки. Если исходное значение содержит меньшее количество цифр, то в начало результирующей строки будут проставлены недостающие нули.

Все вышеуказанные символы могут быть записаны как в верхнем, так и в нижнем регистре.
Параметры index, width, prec могут быть заданы непосредственно числовым значением (например «%8u») или косвенно с помощью символа звездочки (например «%*.*f»). Звездочка означает, что в данной позиции будет использоваться текущее значение из массива данных (соответствующее значение должно представлять собой целочисленное значение), например вызов функции:

В Delphi 7, как мне избежать знака процента ( % ) в функции Format?

Я хочу сделать что-то вроде этого:

но формат не любит этот последний»%», конечно. Так как же мне избежать этого? \% ? %% ?

или я должен это сделать:

4 ответов

используйте другой % в строке формата:

в зависимости от контекста, ваш подход может быть уязвим к SQL-инъекции. Если поисковый запрос исходит от пользовательского ввода, вероятно, лучше использовать параметризованный запрос или, по крайней мере, попытаться санировать ввод.

Delphi FormatFloat and Format functions

I have an application where users can set how values are displayed. The users enter a formatting string and the component uses FormatFloat to display the value.

But now we are using a new third-party component which formats values using the Format function and of course none of our user formats work as the Format & FormatFloat functions use a different syntax.

So does anyone know of a way of converting between the two? Or maybe someone has code to do it?

2 Answers 2

Though the format strings for FormatFloat can be more or less transformed to ones for Format, you may only get real similarity for positive values. The Format method simply doesn’t offer enough flexibility to incorperate the features and fine-grained control that the format strings for the FormatFloat method offers.

For example, the FormatFloat method allows for three different formats for positive, negative and zero values. Also, the FormatFloat format strings allow for string literals, e.g. ‘#,##0.00;;Zero’; (which means that zero values are printed as «Zero»).

To get something similar using the Format function, you yourself would need to do all the grunt work that FormatFloat is doing for you through the format string.

So, although I am as opposed to changing third party control’s sources as I am opposed to changing the vcl sources, I am with David on this one: find a way to make the third party control use the FormatFloat function. Preferably through a custom descendant or through an interposer class (also known as an interceptor class), but if that fails, by all means change the third party control’s source. Just make sure that you mark the changed sections properly so you can easily redo it when switching to a new version of that control.

Есть ли обратная функция * SysUtils.Format * в Delphi

Кто-нибудь написал процедуру «UnFormat» для Delphi?

То, что я представляю, является обратным к SysUtils.Format и выглядит примерно так.

UnFormat (‘число% n и другое% n’, [float1, float2]);

Итак, вы можете распаковать строку в ряд переменных, используя строки формата.

Я просмотрел подпрограмму «Формат» в SysUtils, но я никогда не использовал сборку, поэтому мне это бессмысленно.

Это называется scanf в C, я сделал для него Delphi:

Я знаю, что это пугает людей, но вы можете написать простую функцию для этого, используя регулярные выражения

Если вы беспокоитесь о выражениях reg, посмотрите www.regexbuddy.com, и вы никогда не оглядитесь назад.

Я стараюсь позаботиться об этом, используя простой синтаксический анализатор. У меня есть две функции: одна называется NumStringParts, которая возвращает количество «частей» в строке с конкретным разделителем (в вашем случае над пространством), а GetStrPart возвращает определенную часть из строки с конкретным разделителем. Обе эти процедуры использовались со времен моего Turbo Pascal во многих проектах.

Эти подпрограммы создают чудеса для простых или строгих строк с разделителями-запятыми. Эти подпрограммы прекрасно работают в Delphi 2009/2010.

Посмотрите другие вопросы по меткам function delphi scanf или Задайте вопрос

Format — Функция Delphi

Пишу под Linux на KDevelop

Нужна функция типа format в Delphi/Builder, чтобы возвращала строку

есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),
а нужно чтобы вернула результирующую строку,
можно написать обертку, для sprintf, но я не очень разбираюсь с функциями с неопределенным количеством параметров

От: ZegSoft
Дата: 12.09.11 13:08
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>Пишу под Linux на KDevelop

MAS>Нужна функция типа format в Delphi/Builder, чтобы возвращала строку

MAS>есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),
MAS>а нужно чтобы вернула результирующую строку,
MAS>можно написать обертку, для sprintf, но я не очень разбираюсь с функциями с неопределенным количеством параметров

MAS>вопчем ПАМАГИТЕ

А почему тема Delphi/Builder в ветке C/C++.

От: MASReady
Дата: 12.09.11 13:13
Оценка:

ZS>А почему тема Delphi/Builder в ветке C/C++.

потому что MAS>>Пишу на c/c++ под Linux на KDevelop
читаем вопрос внимательней

От: ДимДимыч http://klug.org.ua
Дата: 12.09.11 13:38
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),

От: MASReady
Дата: 12.09.11 14:25
Оценка:

Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, MASReady, Вы писали:

MAS>>есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),

ДД>есть vsprintf().

vsprintf тоже int возвращает, а не строку
int vsprintf (char * str, const char * format, va_list arg );

От: uzhas
Дата: 12.09.11 14:46
Оценка: +1
От: MASReady
Дата: 12.09.11 15:03
Оценка:

можно сделать при помощи boost::format, QString и иже с ними, но это сильно все усложняет

нужна простая C-шная реализация

От: ДимДимыч http://klug.org.ua
Дата: 12.09.11 15:11
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>vsprintf тоже int возвращает, а не строку
MAS>int vsprintf (char * str, const char * format, va_list arg );

Строку он кладет в char * str. Поэтому, кстати, настоятельно рекомендуется использовать vsnprintf(), чтобы не произошло переполнения буфера.
В GNU C library есть еще vasprintf(), которая сама распределяет память для строки.

От: Ops
Дата: 12.09.11 15:43
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>Пишу под Linux на KDevelop

MAS>Нужна функция типа format в Delphi/Builder, чтобы возвращала строку

MAS>есть sprintf, но она возвращает int(кол-во символов в результате или ошибку),
MAS>а нужно чтобы вернула результирующую строку,
MAS>можно написать обертку, для sprintf, но я не очень разбираюсь с функциями с неопределенным количеством параметров

MAS>вопчем ПАМАГИТЕ

А обязательно нужна функция, и именно C-style?
Потому что можно например так: http://www.rsdn.ru/forum/cpp/4074684.1.aspx

От: SaZ
Дата: 12.09.11 15:51
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>можно сделать при помощи boost::format, QString и иже с ними, но это сильно все усложняет

MAS>нужна простая C-шная реализация

Настоятельно рекомендую так не делать. Перед употреблением познакомиться с возможными последствиями возврата указателей на локальные переменные.

От: MASReady
Дата: 12.09.11 18:55
Оценка:

Здравствуйте, SaZ, Вы писали:

SaZ>Настоятельно рекомендую так не делать. Перед употреблением познакомиться с возможными последствиями возврата указателей на локальные переменные.

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

От: MASReady
Дата: 13.09.11 09:04
Оценка:

Здравствуйте, SaZ, Вы писали:

SaZ>Здравствуйте, MASReady, Вы писали:

MAS>>можно сделать при помощи boost::format, QString и иже с ними, но это сильно все усложняет

MAS>>нужна простая C-шная реализация

SaZ>Настоятельно рекомендую так не делать. Перед употреблением познакомиться с возможными последствиями возврата указателей на локальные переменные.

SaZ>

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

Илон Маск рекомендует:  Поле для поиска
От: SaZ
Дата: 13.09.11 09:57
Оценка: +1

Здравствуйте, MASReady, Вы писали:

MAS>почитал про возврат ссылок (или указателей) на локальные переменные
MAS>но у тебя в коде my_vsnprintf возвращается ссылка не на локальную переменнную, а на полученную во входных параметрах, где здесь может быть проблема?

Я так написал, чтобы не говнокодить писать неудобный код. Вообще, как писали ранее, vsnprintf должна полностью делать то, что тебе нужно. А ещё лучше использовать std::string и прочие, чтобы не городить велосипедов.

От: Michael7
Дата: 13.09.11 20:02
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>Спасибо брат, я как раз подбирался к этому, но не успел
MAS>Скажи где познакомиться с возможными последствиями возврата указателей на локальные переменные.
MAS>Переменная будет скопирована и уничтожена сразу после возвращения, какой может быть здесь криминал?

Локальные переменные выделяются на стеке и после выхода из функции или метода класса там может даже что-то другое оказаться. Особенно, если по дороге где-то неявно еще были вызовы функций (умные указатели, перегруженные операторы и т.п.)

В принципе можно даже segfault словить.

От: dmitryalexeeff
Дата: 14.09.11 02:08
Оценка: 1 (1) -1

1. Если уж пишешь на C, то нужно понимать его . суть. А суть такая что это почти ассемблер по своей идеологии. А так как всем охота иметь строки произвольной длинны, и ни один нормальный человек не будет передавать через стек (а именно через стек и возвращаются все результаты работы функций) кусок данных потенциально бесконечного размера, ну или просто достаточно крупного размера. Поэтому в C, функции не возвращают строки! На крайняк они возвращают УКАЗАТЕЛИ на строки. ( char и char* это как-бе разные вещи )
2. А как-же работают все строковые функции? Есть два метода, либо они сами выделяют память, шаманят в ней, а потом возвращают указатель char* на выделенный блок ( но это как-бе нестандартный для C подход ). Второй метод подразумевает что вы САМИ выделили кусок динамической памяти для строки, запомнили адрес этого куска в типизированном указателе char* ( то есть типа строку создали ) и передаёте этот указатель в строковую функцию, которая через указатель лезет в выделенный вами блок памяти и делает с ним разные интимные вещи.

То есть, если говорить о способах реализации и использования строковых функций в C, то :
А. Есть общепринятый велосипед с передачей в функцию указателя на уже инициализированную строку
Б. Есть другие велосипеды, реже используемые, с квадратными колёсами, но работоспособные

P.S. И да, в C++ можно возвращать из функции строки, не парясь с выделением памяти и указателями. Эти возможности реализуются либо стандартной библиотекой языка C++, либо сторонними библиотеками, из которых я могу назвать Qt, boost
P.P.S. И да, C и C++ это разные языки

От: MASReady
Дата: 19.09.11 13:57
Оценка:

Здравствуйте, dmitryalexeeff, Вы писали:

D>1. Если уж пишешь на C, то нужно понимать его . суть. А суть такая что это почти ассемблер по своей идеологии. А так как всем охота иметь строки произвольной длинны, и ни один нормальный человек не будет передавать через стек (а именно через стек и возвращаются все результаты работы функций) кусок данных потенциально бесконечного размера, ну или просто достаточно крупного размера. Поэтому в C, функции не возвращают строки! На крайняк они возвращают УКАЗАТЕЛИ на строки. ( char и char* это как-бе разные вещи )
D>2. А как-же работают все строковые функции? Есть два метода, либо они сами выделяют память, шаманят в ней, а потом возвращают указатель char* на выделенный блок ( но это как-бе нестандартный для C подход ). Второй метод подразумевает что вы САМИ выделили кусок динамической памяти для строки, запомнили адрес этого куска в типизированном указателе char* ( то есть типа строку создали ) и передаёте этот указатель в строковую функцию, которая через указатель лезет в выделенный вами блок памяти и делает с ним разные интимные вещи.

D>То есть, если говорить о способах реализации и использования строковых функций в C, то :
D>А. Есть общепринятый велосипед с передачей в функцию указателя на уже инициализированную строку
D>Б. Есть другие велосипеды, реже используемые, с квадратными колёсами, но работоспособные

D>P.S. И да, в C++ можно возвращать из функции строки, не парясь с выделением памяти и указателями. Эти возможности реализуются либо стандартной библиотекой языка C++, либо сторонними библиотеками, из которых я могу назвать Qt, boost
D>P.P.S. И да, C и C++ это разные языки

это все понятно,

От: SaZ
Дата: 19.09.11 15:01
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>это все понятно,

MAS>я про то что:
MAS>

Это всё страшное извращение, чреватое кучей ошибок). Зачем это нужно? Как тут уже выше давали ссылку, вот нормальный подход

От: dmitryalexeeff
Дата: 20.09.11 00:46
Оценка:

Здравствуйте, MASReady, Вы писали:

MAS>

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

От: MASReady
Дата: 27.10.11 06:09
Оценка:

Вот что получилось в итоге, мож кому пригодится, главное не забыть когда строка станет ненужной сделать ей free
может и не супер стильно зато стабильно и удобно.

Format — Функция Delphi

При задании значения даты-времени следует обратить внимание не только на сами значения, но и на знаки препинания. Несущественные части даты-времеи (например, секунды, минуты, часы) можно справа отбросить. В этом случае считается, что соответствующая часть равна нулю. Если в дате-времени отброшено еще и значение года, считается, что имеется в виду текущий год. Обычно тип дата-время используется в параметрах вариантного типа как один из допустимых вариантов, но может использоваться и самостоятельно для фиксации информации о времени.

Примечание. Следует иметь в виду, что при записи года двумя последними цифрами фактический год зависит от текущего года и глобальной переменной заданной в Delphi — TwoDigitYearCenturyWindow. По умолчанию эта переменная имеет значение, равное 50, что означает, что в конце этого столетия и начале следующего задаваемые двумя цифрами годы будут относиться к XX в., если число несколько больше 50, и к XXI в., если число несколько меньше 50.

В модуле SysUtils определен ряд стандартных функции работы с параметрами типа даты-времени.

  • Time — текущее время. Функция возвращает текущее значение времени в формате TTime.
  • Date — текущая дата. Функция возвращает текущее значение даты в формате TDate.
  • Now — текущая дата и время. Функция возвращает текущее значение даты и времени в формате TDateTime.
  • DateTimeToStr (DateTime) — символьное представление даты и времени. Функция формирует для параметра DateTime типа TDateTime символьное представление даты и времени с учетом региональной установки Windows и возвращает полученную строку в качестве результата своей работы.
  • DateTimeToString (Result, Format, DateTime) — сформатированное символьное представление даты и времени. Процедура формирует символьное представление параметра DateTime типа TDateTime с учетом формата, заданного строкой Format, и помещает результат в строку Result.
  • DateToStr (Date) — символьное представление даты. Функция формирует для параметра Date типа TDateTime или TDate символьное представление даты с учетом региональной установки Windows и возвращает полученную строку в качестве результата своей работы.
  • DayOfWeek (Date) — день недели. Функция возвращает день недели заданной даты Date типа TDateTime или TDate в виде числа от 1 до 7, причем нумерация начинается с воскресенья.
  • TimeToStr (Time) — символьное представление времени. Функция формирует для параметра Time типа TDateTime или TTime символьное представление времени с учетом региональной установки Windows и возвращает полученную строку в качестве результата своей работы.
  • DecodeDate (Date, Year, Month, Day) — выделение в дате года, месяца, дня. Процедура выделяет из параметра Date типа TDateTime или TDate год, месяц, день и помещает их соответственно в параметры Year, Month и Day типа Word.
  • DecodeTime (Date, Hour, Min, Sec, MSec) — выделение во времени часа, минуты, секунды и числа миллисекунд. Процедура выделяет из параметра Date типа TDateTime или TTime час, минуту, секунду и число миллисекунд и помещает их соответственно в параметры Hour, Min, Sec и MSec типа Word.
  • EncodeDate (Year, Month, Day) — формирование даты из компонент. Функция формирует из заданного года, месяца и дня (заданных в параметрах Year, Month, Day) комплексный параметр типа TDateTime и возвращает его как результат работы.
  • EncodeTime (Hour, Min, Sec, MSec) — формирование времени из компонент. Функция формирует из заданных часа, минуты, секунды и числа миллисекунд (заданных в параметрах Hour, Min, Sec, MSec) комплексный параметр типа TDateTime и возвращает его как результат работы.
  • FormatDateTime (Format, DateTime) — сформатированное символьное представление даты и времени. Функция формирует символьное представление параметра DateTime типа TDateTime с учетом формата, заданного строкой Format, и возвращает полученную строку как результат своей работы.
  • StrToDate (S) — преобразование символьного представления даты в тип TDateTime. Функция преобразовывает символьное представление даты, находящееся в строке S, в формат TDateTime или TDate и возвращает полученную величину как результат своей работы. Дата должна быть задана в соответствии с региональной установкой Windows.
  • StrToTime (S) — преобразование символьного представления времени в тип TDateTime. Функция преобразовывает символьное представление времени, находящееся в строке S, в формат TDateTime или TTime и возвращает полученную величину как результат своей работы. Время должно быть задано в соответствии с региональной установкой Windows.
  • StrToDateTime (S) — преобразование символьного представления даты и времени в тип TDateTime. Функция преобразовывает символьное представление даты и времени, находящееся в строке S, в формат TDateTime и возвращает полученную величину как результат своей работы. Дата и время должны быть заданы в соответствии с региональной установкой Windows.

Тепеть разберем некоторые функции на примерах.

DateTimeToString

DateTimeToStr

DateToStr

TimeToStr

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

Обновлять информацию о времени будем, используя таймер, и сделаем возможность запуска/остановки часов. Запускать и останавливать таймер будем следующей процедурой.

Таймер, через определенные интервалы времени, будет получать информацию о дате и времени, выводить ее, и вызывать процедуру рисования аналоговых часов.

А вот и сама процедура рисования аналоговых часов.

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

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL