printf для wsh vbs.
Aug. 9th, 2015 04:58 pmВыкрутиться можно используя net.
function fmt(str,args)
dim oSB : set oSB=CreateObject(System.Text.StringBuilder)
oSB.AppendFormat_4 str, (args)
fmt = oSB.ToString()
set oSB=Nothing
end function
Но у него неудобная строка формата: надо указывать порядковые номера параметра, что может привести к путанице.
Каждый элемент форматирования имеет следующий вид и состоит из следующих компонентов:
{ index[,alignment][:formatString]}
Парные фигурные скобки ("{" и "}") здесь обязательны.
Индекс
Обязательный компонент index, также называемый описателем параметра, — это число, определяющее соответствующий объект из списка; индексация элементов ведется от нуля.
<...>
Выравнивание
Необязательный компонент alignment — это целое число со знаком, которое служит для указания желательной ширины поля форматирования.
<...>
Компонент строки формата
Необязательный компонент formatString — это строка формата, соответствующая типу форматируемого объекта. Если соответствующий объект является объектом DateTime, то используется строка стандартного или настраиваемого формата чисел, а если соответствующий объект является значением перечисления, то используется строка формата перечисления. Если компонент formatString не задан, то для числовых значений, значений даты и времени, а также перечислений используется общий формат ("G"). При использовании компонента formatString необходимо двоеточие.
<...>
Оформление фигурных скобок
Начало и конец элемента форматирования обозначаются соответственно открывающей и закрывающей фигурной скобкой.
Поэтому я создал функцию fmt, аналогичную printf.
function fmt( str, args )
dim res ' the result string.
dim val,justification,prnpls,prnsys,width,spcchar,precision
res = ""dim pos ' the current position in the args array.
pos = 0dim i
for i = 1 to Len(str)
' found a fmt char.
if Mid(str,i,1)="%" then
val="":justification="r":prnpls="":prnsys=false:width=0:precision=0:spcchar=" "
i=i+1
if Mid(str,i,1)="%" then
res = res & "%"
else
'поиск флагов
do while true
select case Mid(str,i,1)
case "-"
i=i+1 : justification="l"
case "+"
i=i+1 : prnpls="+"
case " "
i=i+1 : prnpls=" "
case "#"
i=i+1 : prnsys=true
case "0"
i=i+1 : spcchar="0"
case else
exit do
end select
loop
'ширина поля, если цифра
if Mid(str,i,1)="*" then
width=args(pos):pos = pos+1:i = i + 1
else
while (Asc(Mid(str,i,1))-asc("0"))<=9 and (Asc(Mid(str,i,1))-asc("0"))>=0
width=width*10+Asc(Mid(str,i,1))-asc("0")
i=i+1
wend
end if
'точность
if Mid(str,i,1)="." then
i=i+1
precision=0
if Mid(str,i,1)="*" then
precision=args(pos):pos = pos+1:i = i + 1
else
while (Asc(Mid(str,i,1))-asc("0"))<=9 and (Asc(Mid(str,i,1))-asc("0"))>=0
precision=precision*10+Asc(Mid(str,i,1))-asc("0")
i=i+1
WEND
end if
if precision=0 then precision=-1
end if
'тип значения
select case Mid(str,i,1)
case "d"
'целое со знаком
val=FormatNumber(abs(args(pos)),0,,false,false)
if args(pos)<0 then prnpls="-"
if spcchar="0" then precision=width-len(prnpls)
if len(val)<precision then val=String(precision-len(val),"0")&val
val=prnpls&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
case "i"
val=FormatNumber(abs(args(pos)),0,,false,false)
if args(pos)<0 then prnpls="-"
if spcchar="0" then precision=width-len(prnpls)
if len(val)<precision then val=String(precision-len(val),"0")&val
val=prnpls&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
'целое без знака
case "u"
val=FormatNumber(abs(args(pos)),0,,false,false)
if spcchar="0" then precision=width-len(prnpls)
if len(val)<precision then val=String(precision-len(val),"0")&val
val=prnpls&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
'восьмиричное
case "o"
val=Oct(args(pos))
if prnsys=true then
prnsys="0"
else
prnsys=""
end if
if spcchar="0" then precision=width-len(prnsys)
if len(val)<precision then val=String(precision-len(val),"0")&val
val=prnsys&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
case "x"
'шестнадцетиричное
val=LCase(Hex(args(pos)))
if prnsys=true then
prnsys="0x"
else
prnsys=""
end if
if spcchar="0" then precision=width-len(prnsys)
if len(val)<precision then val=String(precision-len(val),"0")&val
val=prnsys&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
case "X"
'шестнадцетиричное
val=UCase(Hex(args(pos)))
if prnsys=true then
prnsys="0X"
else
prnsys=""
end if
if spcchar="0" then precision=width-len(prnsys)
if len(val)<precision then val=String(precision-len(val),"0")&val
val=prnsys&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
'с точкой
case "f"
if precision=-1 then
val=FormatNumber(abs(args(pos)),0,,false,false)
elseif precision=0 then
val=FormatNumber(abs(args(pos)),,,false,false)
else
val=FormatNumber(abs(args(pos)),precision,,false,false)
end if
if prnsys=true then
if InStr(val,".")=0 then val=val&"."
else
if mid(val,len(val),1)="." then val=mid(val,1,len(val)-1)
end if
if args(pos)<0 then prnpls="-"
if spcchar="0" then
if width>(len(val)+len(prnpls)) then
val=String(width-len(val)-len(prnpls),"0")&val
end if
end if
val=prnpls&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
case "F"
if precision=-1 then
val=FormatNumber(abs(args(pos)),0,,false,false)
elseif precision=0 then
val=FormatNumber(abs(args(pos)),,,false,false)
else
val=FormatNumber(abs(args(pos)),precision,,false,false)
end if
if prnsys=true then
if InStr(val,".")=0 then val=val&"."
else
if mid(val,len(val),1)="." then val=mid(val,1,len(val)-1)
end if
if args(pos)<0 then prnpls="-"
if spcchar="0" then
if width>(len(val)+len(prnpls)) then
val=String(width-len(val)-len(prnpls),"0")&val
end if
end if
val=prnpls&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
'научное представление
case "e"
exponent=int(log(args(pos))/log(10))
mantissa=args(pos)/10^exponent
if precision=-1 then
val=FormatNumber(abs(mantissa),0,,false,false)
elseif precision=0 then
val=FormatNumber(abs(mantissa),,,false,false)
else
val=FormatNumber(abs(mantissa),precision,,false,false)
end if
if prnsys=true then
if InStr(val,".")=0 then val=val&"."
else
if mid(val,len(val),1)="." then val=mid(val,1,len(val)-1)
end if
val=val&"e"
if exponent>=0 then val=val&"+"
val=val&exponent
if mantissa<0 then prnpls="-"
if spcchar="0" then
if width>(len(val)+len(prnpls)) then
val=String(width-len(val)-len(prnpls),"0")&val
end if
end if
val=prnpls&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end ifcase "E"
exponent=int(log(args(pos))/log(10))
mantissa=args(pos)/10^exponent
if precision=-1 then
val=FormatNumber(abs(mantissa),0,,false,false)
elseif precision=0 then
val=FormatNumber(abs(mantissa),,false,false)
else
val=FormatNumber(abs(mantissa),precision,,false,false)
end if
if prnsys=true then
if InStr(val,".")=0 then val=val&"."
else
if mid(val,len(val),1)="." then val=mid(val,1,len(val)-1)
end if
val=val&"E"
if exponent>=0 then val=val&"+"
val=val&exponent
if mantissa<0 then prnpls="-"
if spcchar="0" then
if width>(len(val)+len(prnpls)) then
val=String(width-len(val)-len(prnpls),"0")&val
end if
end if
val=prnpls&val
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
'символ
case "c"
val=Left(args(pos),1)
'строка
case "s"
val=mid(args(pos),1,precision)
if len(val)<width then
if justification="r" then
val=String(width-len(val)," ")&val
else
val=val&String(width-len(val)," ")
end if
end if
case else
val=0 : val=val/val 'исключение по ошибке
end select
res=res&val
pos=pos+1
end if' found a normal char.
else
res = res & Mid(str,i,1)
end if
next
fmt = res
end function
Строка формата аналогичная printf.
Пример вызова.
MsgBox fmt ("%+010.6f",Array(45.678))
