【问题标题】:VBScript - Pass for loop iterations into dynamic arrayVBScript - 将循环迭代传递到动态数组
【发布时间】:2015-05-01 09:23:53
【问题描述】:

我有这段代码,它将每个 for 循环迭代结果输出到一个消息框:

dim str

str = inputbox("Please enter character string for encryption","Encryption")

for i=1 to len(str)
wscript.echo asc(mid(str,i,1)) - (i-1)  
next

我想将每次迭代的结果存入一个数组,然后将整个数组内容以字符串的形式显示在消息框中。

我正在尝试这样的事情:

dim str, arr()

str = inputbox("Please enter character string for encryption","Encryption")

for i=1 to len(str)
redim preserve arr(ubound(arr)+1)
arr(ubound(arr)) = asc(mid(str,i,1)) - (i-1)    
next

wscript.echo arr

但得到第 6 行:错误: 下标超出范围'ubound'。在将它映射到数组之前,我应该通过函数调用迭代吗?

【问题讨论】:

    标签: arrays for-loop vbscript


    【解决方案1】:

    这是我修改后的功能齐全的代码,感谢您的帮助...

    dim str, arr, arr2, result, ls, i, encstr, decstr
    
    do while len(str)=0
    str = inputbox("Please enter character string for encryption","Cipher")
    if isempty(str) then
    wscript.quit()
    end if
    loop
    
    ls=(len(str))
    redim arr(ls -1)
    for i=1 to ls
    arr(i-1) = chr(asc(mid(str,i,1)) - (i-1))
    next
    encstr = join(arr,"")
    rem wscript.echo encstr
    
    ls=len(encstr)
    redim arr2(ls-1)
    for i=1 to ls
    arr2(i-1) = chr(asc(mid(encstr,i,1)) + (i-1))
    next
    decstr=join(arr2,"")
    rem wscript.echo decstr
    
    result=msgbox("Encrypted string: " & encstr & vbcrlf & "Decrypted string: " & decstr,0,"Cipher")
    

    【讨论】:

      【解决方案2】:

      (1) UBound() 不会在空数组上失败,它会返回 -1(与只有一个元素的数组一样少一个):

      >> Dim a : a = Array()
      >> WScript.Echo TypeName(a), UBound(a)
      >> ReDim a(UBound(a)+1)
      >> a(Ubound(a)) = "one and only"
      >> WScript.Echo TypeName(a), UBound(a), a(0)
      >>
      Variant() -1
      Variant() 0 one and only
      

      (2) UBound() 对a() 失败,因为a() 不是一个空数组,而是一个可憎的东西——一个没有大小的固定数组——编译器/解释器太愚蠢而无法捕捉。你不能用 a() 做任何事情,除了用一些有用的东西覆盖/替换变量。

      (3) UBound() 永远不会返回 undefined(VBScript 中没有 undefined),而是一个数字。

      (4) 将循环计数器用于字符串位置 (1...) 数组索引 (0...) 是错误的;您的数组将在头部包含空元素。

      (5) 将字符串元素的计算存储到相应数组中的正确方法是使用有关字符串长度的知识来避免代价高昂的 ReDim Preserve:

      >> s = "abc"
      >> ReDim a(Len(s) - 1)
      >> For p = 1 To Len(s) : a(p - 1) = Chr(Asc(Mid(s, p, 1)) - 32) : Next
      >> WScript.Echo Join(a), Join(a, "")
      >>
      A B C ABC
      

      【讨论】:

      • 我现在明白了很多,谢谢 Ekkehard。由于您在您的观点中说明的原因,我在解密相同的字符串(超出数组大小的值)时遇到了问题。我已经重写了我的代码,我会在检查后将它发布在这里(对于它可能会引起的批评方式感到非常恐惧)。
      【解决方案3】:

      如果您喜欢使用 XOR 运算符的另一种加密方法:

      Option Explicit
      'Déclaration des variables globales
      Dim Titre,MaChaine,fso,ws,LogFile,ChaineCrypt
      'Titre du Script
      Titre = "Cryptage d'une chaîne de caractères by Hackoo"
      Set fso = CreateObject("Scripting.FileSystemObject")
      Set ws = CreateObject("Wscript.Shell")
      'Nom du fichier qui va stocker le résultat
      LogFile = Left(Wscript.ScriptFullName,InstrRev(Wscript.ScriptFullName, ".")) & "txt"
      if fso.FileExists(LogFile) Then 'Si le fichier LogFile existe 
          fso.DeleteFile LogFile 'alors on le supprime
      end If
      'La boîte de saisie de la chaîne de caractères
      MaChaine = InputBox("Taper votre chaîne ou bien une phrase pour la crypter",Titre,"www.stackoverflow.com")
      'Si la Chaîne est vide ou bien on ne tape rien dans l'inputbox,alors on quitte le script
      If MaChaine = "" Then Wscript.Quit 
      ChaineCrypt = Crypt(MaChaine,"2015")
      MsgBox DblQuote(MaChaine) &" est transformée en "& VbCrlF & VbCrlF & DblQuote(ChaineCrypt),Vbinformation,Titre
      Call WriteLog(ChaineCrypt,LogFile)
      ws.run LogFile
      '************************************************************************
      Function Crypt(text,key) 
      Dim i,a
      For i = 1 to len(text)
            a = i mod len(key)
            if a = 0 then a = len(key)
            Crypt = Crypt & chr(asc(mid(key,a,1)) XOR asc(mid(text,i,1)))
      Next
      End Function
      '*****************************************************************
      'Fonction pour ajouter des guillemets dans une variable
      Function DblQuote(Str)
          DblQuote = Chr(34) & Str & Chr(34)
      End Function
      '*****************************************************************
      'Fonction pour écrire le résultat dans un fichier texte
      Sub WriteLog(strText,LogFile)
          Dim fs,ts 
          Const ForAppending = 8
          Set fs = CreateObject("Scripting.FileSystemObject")
          Set ts = fs.OpenTextFile(LogFile,ForAppending,True)
          ts.WriteLine strText
          ts.Close
      End Sub
      '*****************************************************************
      

      【讨论】:

      • 没有解决这个问题。
      【解决方案4】:

      您的代码不正确,因为 UBound 在空数组上失败,它返回 undefined。

      为什么不用“i”这样的索引(我测试过):

      for i=1 to len(str)
          redim preserve arr(i+1)
          arr(i) = asc(mid(str,i,1)) - (i-1)    
      next
      

      另外,打印数组的语法是错误的,请使用以下内容:

      for j=1 to i
          WScript.Echo arr(j)
      next
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-28
      • 2021-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      相关资源
      最近更新 更多