Форум "Delphi" (архив)
Паскаль, Делфи
Тест для мастеров DelphiДля удобного форматирования строк существует хорошая функция function Format(const Format: string; const Args: array of const): string; Однако, у нее есь маленький недостаток, она работает только с массивом констант : function Format(const Format: string; const Args: array of const): string; Однако, у нее есь маленький недостаток, она работает только с массивом констант. Внимание, тестовое задание: нужно написать функцию-обертку, которая бы вызывала эту функцию, но на входе могла принимать динамически сформированный массив(естественно, нужной размерности). Предоставленное решение -- хорошая заяка на получение титула авторитета на нашем форуме.
: |
|
шо-то не могу себе представить, как дельфя это пропустит... нереально... кстати, никогда эту ф-цию не пользовал, как-то обходился FormatFloat, FormatDateTime. вообще, не очень понял, нафик она нужна? в хелп пофтыкал, сильно много буковок, обломался разбираца |
|
#2 Go © 28.02.06 12:05:15
хорошая заяка на получение титула авторитета на нашем форуме хм.. может подумать!? |
|
А де Дельфю взять? Уж больно авторитетом хочется стать. |
|
>#1 Паша © напрямую не пропустит. А в небольшой обход - можно. >#2 Go © ага, тем более что ты(насколько я знаю из нашего общения) очень близка к правильному ответу >#3 Лысый © на компактах имеецца |
|
А можно стать авторитетом в Си? Решение для Си: sprintf(); >#3 Лысый © К меня с собой есть Билдер, он код Дельфи понимает. |
|
> #5 VictorT © нет, для си -- это слишком легкая добыча, там нужно другую задачку придумывать |
|
ответы сюда выкладывать или как? (= |
|
#8 maximus © 28.02.06 13:10:12
конечно интересно было бы сделать такое, но я не знаю даже как формат работает, не использовал никогда... |
|
#9 maximus © 28.02.06 13:23:49
Накопал только такое: СТРОКИ ФОРМАТИРОВАНИЯ При форматировании строк с помощью функций Format, FormatBuf, StrFmt, StrLFmt, процедуры FmtStr, в качестве одного из параметров, в данных подпрограммах используется строка форматирования. Строка форматирования может содержать в себе два типа объектов - обычные символы и спецификаторы (команды форматирования). Обычные символы копируются один к одному в результирующую строку. Спецификаторы применяются для выборочного форматирования элементов из списка аргументов. Общий вид спецификатора можно представить в следующем виде: "%" [index ":"] ["-"] [width] ["." prec] type Спецификатор начинается с символа %. За ним следуют: Необязательный параметр [index ":"], задающий индекс аргумента. Индикатор выравнивания по левому краю ["-"] (необязательный параметр). Необязательный параметр [width], задающий минимальную длину результирующей строки. Необязательный параметр ["." prec], задающий точность. Символ преобразования типа, type. Идентификатор 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, задает минимальное количество символов результирующей строки. Если исходное значение содержит меньшее количество цифр, то в начало результирующей строки будут проставлены недостающие нули. |
|
#10 maximus © 28.02.06 13:24:32
Все вышеуказанные символы могут быть записаны как в верхнем, так и в нижнем регистре. Параметры index, width, prec могут быть заданы непосредственно числовым значением (например "%8u") или косвенно с помощью символа звездочки (например "%*.*f"). Звездочка означает, что в данной позиции будет использоваться текущее значение из массива данных (соответствующее значение должно представлять собой целочисленное значение), например вызов функции: Format( '%*.*f', [ 9, 2, 12345.6789 ] ); аналогичен Format( '%9.2f', [ 12345.6789 ] ); Результирующей строкой в обоих случаях будет '12345.68' Параметр width задает минимальную длину результирующей строки. Если количество символов в получаемой строке меньше значения width, то строка дополняется необходимым количеством пробелов. По умолчанию пробелы добавляются в начало строки. Для того, чтобы пробелы добавлялись в конец строки необходимо в строку формата перед параметром width поставить символ "-". Параметр index определяет, какой элемент массива данных будет подвергаться форматированию. Первый элемент массива имеет индекс 0. После числового значения индекса должен стоять символ двоеточия ":". Если параметр index опускается, то форматируется элемент следующий за элементом который подвергался форматированию в прошлый раз (Первое форматирование соответственно производится для первого элемента массива данных). Например, вызов функции: Format( '%3d, %d, %0:d, %2:-4d, %d', [ 1, 2, 3, 4 ] ); будет возвращать следующую строку ' 1,2,1,3 ,4' |
|
> #7 FonMax © давай для начала на мыло(admin#webest.net), может еще кому интересно будет покопаться над задачкой. |
|
> на компактах имеецца или из сети скачай ээээ... я шутил вообще-то |
|
> нет, для си -- это слишком легкая добыча, там нужно другую > задачку придумывать Ага, я ведь уже и готовое решение показал. Кстати, могу подкинуть ещё задачку на конкурс. Тоже совершенно не задачка для Си, но не знаю, как сейчас для Дельфи. Когда-то давно мне в паскале очень не хватало. Речь идёт о перегрузке операторов. |
|
> Речь идёт о перегрузке операторов. насколько мне известно, в паскале имеется только перегрузка процедур и функций. |
|
>#4 Deep © 28.02.06 15:35:56 > напрямую не пропустит. А в небольшой обход - можно ну, ежели с указателями, то пропустит... только насколько это все дело будет надежно работать - не знаю. может и свалицца. или через приведение типов, навскидку, тестировать шо-то лениво: type TArrConst: array of constr; ну, и потом, function ddd(ss: string; arr: array of integer) var zz: TArrConst; begin zz:= TArrConst(arr); дальше ясно. |
|
>#15 Паша © если честно не понял механизам реализации. Не вижу возможности подсунуть функции динамически сформированный массив. Может плохо описал, детализирую: есть строка s := 'xxxxxx %s xxxxxxxxxx %s xxxxxxxxxxxxxxxxxxxxxxx' в нее нужно подставлять два параметра (видим в строке два %s) только вот вся задача в том, что подставлять каждый раз значения разных переменных. 1) Format(s, [a1, b1]); 2) Format(s, [a4, b12]); 3) Format(s, [a3, b8]); и т.д. причем переменные которые подставляются по большому счету заранее не известны, они определяются в рантайм по условиях. Нужна функция Format(s, arr); где arr -- массив заранее неопределенных переменных Синтаксис вызова должен быть примерно таков SetLength(arr, 3); arr[0] := '123 dfsgd'; arr[1] := 234; arr[2] := 34523.4; Format(s, arr); |
|
все таки поробовал. полную фигню я написал. |
|
#18 Mystic © 28.02.06 15:40:35
Объявление array of const эквивалентено array of TVarRec. Объяви переменную arr как <v>array of TVarRec</v>, создавай ее динамически и передавай все что только сможешь передать! |
|
>#18 Mystic © эта сволочная ф-ция не хочет принимать переменную типа массив констант. хотя, вероятно я криво это дело написал. |
|
#20 Mystic © 28.02.06 16:44:20
> эта сволочная ф-ция не хочет принимать переменную типа массив > констант. хотя, вероятно я криво это дело написал. Нельзя описать переменную типа array of const. Потому что array of const это синоним для array of TVarRec при объявлении параметров. Поэтому функция Format может принимать вторым параметром как конструктор массива (перечень элементов в квадратных скобках), так и переменную типа array of TVarRec. |
|
>#20 Mystic © направление правильное только бы еще реализацию увидеть |
|
#22 АБС 28.02.06 16:57:31
procedure TForm1.Button1Click(Sender: TObject); var Arr: array of TVarRec; begin SetLength(Arr, 3); Arr[0].VType := vtAnsiString; Arr[1].VType := vtAnsiString; Arr[2].VType := vtAnsiString; Arr[0].VAnsiString := PChar(Edit1.Text); Arr[1].VAnsiString := PChar(Edit2.Text); Arr[2].VAnsiString := PChar(Edit3.Text); Edit4.Text := Format('%s %s %s', Arr); end; |
|
#23 isasa 28.02.06 16:59:13
Если я привильно поня, то у меня работает так. function TrprtForm.StrRes(i: integer): string; var buf : PChar; begin buf:=strAlloc(MaxMsgLen); LoadString(resHnd, i, buf, MaxMsgLen); Result:=StrPas(buf); strDispose(buf); end; function TrprtForm.ParseLine(const id: integer; vals: array of TVarRec) : string; var s: string; i: integer; begin try Result:=Format(StrRes(id), vals); except on e:Exception do begin s:='('+IntToStr(id)+') '; for i:=low(vals) to high(vals) do s:=s+sType[vals[i].VType]+'|'; Result:=s+' "'+StrRes(id)+'" '+E.Message; exit; end; end; end; resHnd - хандлер на библиотеку(dll) ресурсов ресурсы, естественно содержат строки с элементами ыорматирования(%s, %d...) вызовы ParseLine(12300,[]); ParseLine(12303,[StrRes(1010+pData^.Ts)]); ParseLine(12309,[StrRes(1097), pData^.T[0]]); ParseLine(12310,['K',IProp.T]); |
|
#24 isasa 28.02.06 17:00:39
Deep : дубль
|
|
#25 isasa 28.02.06 17:01:15
Сорри за дубль, упал IE |
|
> Нельзя описать переменную ну да, я неверно выразился. объявлял массив констант, и пытался его туда всунуть |
|
>#22 АБС зачот вобщем-то >#23 isasa тоже вариант только вызовы > вызовы > > ParseLine(12300,[]); > ParseLine(12303,[StrRes(1010+pData^.Ts)]); > ParseLine(12309,[StrRes(1097), pData^.T[0]]); > ParseLine(12310,['K',IProp.T]); > нужно было оформить как описано выше, а то получается что вызывается все-таки заранее определенный, а не динамически сормированный массив констант. |
|
#28 isasa 28.02.06 21:49:46
function TrprtForm.ParseLine(const id: integer; vals: array of TVarRec) : string; ... Result:=Format(StrRes(id), vals); От const ушли, этого достаточно. А писать ParseLine(..., [Edit1.Text, Edit2.Text, Edit3.Text]); или как в [22] дело вкуса. |
|
>#28 isasa |
Тема находится в архиве
Написать ответ |
|
