zepete: (Default)
[personal profile] zepete
Скрипты для windows лучше всего писать на vbs, ибо на нем легче обращаться к wmi, но в vbs не предусмотрено функции printf.
Выкрутиться можно используя 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 = 0

 dim 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 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 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))

Profile

zepete: (Default)
zepete

January 2026

S M T W T F S
    1 23
4 56 78910
11121314151617
18192021222324
25262728293031

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 14th, 2026 12:18 am
Powered by Dreamwidth Studios