将数组与 Instr 一起使用

Using Array with Instr

我正在使用 VB6 创建一个聊天机器人,这个聊天机器人的全部基础是每当用户写 'trigger word',例如 "good"、"amazing" 等时,聊天机器人将回复 "that's great"。 但是,每当我不写触发词时,只会出现 "Word is in this" 的消息框,而且我不知道自己做错了什么。我试过摆弄 >、<、= 标志,但无济于事。任何帮助将不胜感激。

  Private Sub conversation()
    Dim imput As String 'where user types to chatbot

    Dim arrWords As Variant, aWord As Variant
    arrWords = Array("good", "great", "bad")

    Dim wordFound As Boolean
    wordFound = False
    For Each aWord In arrWords
        If InStr(imput, aWord) = 0 Then
            wordFound = True And MsgBox "Word is in this"
        ElseIf InStr(imput, aWord) > 0 Then
            wordFound = False And MsgBox "Word is not in this"
        End If
    Next
End Sub

我没有尝试 运行 你的代码——它甚至看起来都不像 运行——但至少会跳出一个错误。

If InStr(imput, aWord) = 0 Then
  wordFound = True And MsgBox "Word is in this"'

...并不像您认为的那样。你是说当输入 (InStr = 0) 中不存在单词时 wordFound 为真,但仅当 MsgBox returns 为非零结果时

你想要的是这样的:

If InStr(imput, aWord) > 0 Then  ' >0 means word was found
  wordFound = True 
  MsgBox "Word is in this"'

'not found'条件平行成立。

Jim Mack 的回答是正确的;我会通过添加(在 for 循环之前)使比较更加稳健:

  imput = UCase(imput)

并使测试词数组全部大写。从根本上说,原始代码只是存在逻辑问题(可能是由于对语言的误解)。

ElseIf 子句也有些令人担忧;一般来说,包含一个明确的 else 子句来处理任何满足所有先前条件的测试是明智的。

其他答案已经说明你的逻辑是反的,确实如此。

而且,我不知道你是否准确地复制了你的代码,但是当我将它复制到 VB 时,我得到了——如我所料——[= 行的语法错误13=] 在其中。我可以通过在 MsgBox 参数中添加圆括号来 "fix",所以:wordFound = True And MsgBox("Word is in this"),等等。但这不是好的代码,原因我会解释,我还有一些其他的代码建议。

考虑对您的代码进行这些更改:

Private Sub conversation(theInput As String)

    Dim arrWords As String, aWord As String
    arrWords = Array("good", "great", "bad")

    Dim wordFound As Boolean
    wordFound = False
    For Each aWord In arrWords
        If InStr(theInput, aWord) = 0 Then
            wordFound = False
            MsgBox """" & aWord & """ is in this"
        Else
            wordFound = True 
            MsgBox """" & aWord & """ is not in this"
        End If
    Next
End Sub

Private Sub SendButton_Click()
    conversation(myChatTextBox.Text)
End Sub

好的。这里有几点。

  1. 除非有令人信服的理由,否则不要使用 Variant。这是存储信息效率最低的方法,因为它必须分配额外的内存以在内部告知它是什么类型的变量,并且它还必须分配足够的内存以包含它可能是的最大可能类型。 (String 变量有 10 个字节加上字符串中的每个字符一个,而分配为字符串的 Variant 类型有 22 个字节加上字符串中的每个字符一个。)
  2. 我把imput改成了theInputinput是VB中的保留字,所以不能用,但不拼错别人就更清楚了。最好找个前缀放在上面。
  3. 正如其他人所说,当 InStr return 为零时,这意味着参数 2 中的字符串不在参数 1 中的字符串中。因此,这意味着 "word isn't in this," 不是这样。 (这就是您遇到的问题的答案;其余部分只是为了整体改进您的代码。)
  4. wordFound = True And MsgBox("Word is in this") 只是巧合。 MsgBox return 当它在没有参数的情况下成功运行时,值为 1。 (谁知道呢?我不得不亲自尝试一下。可能是因为它可以为不同类型的 ms 设置 return 多个不同的值)所以你的逻辑是 wordFound = True And 1And 是逻辑比较运算符:True And 1 的计算结果为 True,而 False And 1 的计算结果为 False。所以,你得到了你想要的,但几乎是偶然的。将两个代码位放在两条不同的线上。您不需要从逻辑上比较它们;事实上这样做没有意义。 (如果你真的想把两行代码放在同一行,在它们之间放一个冒号:wordFound = True : MsgBox "etc",但这通常不被认为是好的做法,因为代码的可读性较差。我有你认为的感觉您使用 And 来执行此操作,正如您所见,它做了一些完全不同的事情。)
  5. 我更改了您的消息,将您要查找的词用引号括起来,例如 "good" is in this。要在字符串中获取文字引号,请使用其中两个:""。 (您必须将这两个引号自己放在引号中,因为它们是带引号的字符串;这就是为什么开头有四个,后面有三个的原因。)
  6. 这里不需要 ElseIf,因为如果你的 If 条件为假,你的 ElseIf 条件为真。如果您正在评估两个以上的可能条件,则只需要 ElseIf
  7. 我已经建立了如何将聊天框用户的输入发送到您的 conversation 子例程的基本思路。当用户单击 Send 按钮时,您将文本框的内容作为 input 参数发送到 conversation。如果将其设置为局部变量,则必须编写某种代码来获取用户的输入。这是完成这项工作的更简洁的方法。

综上所述,您可以像这样进一步简化 For Each 循环:

For Each aWord In arrWords
    wordFound = InStr(input, aWord) > 0 
    MsgBox """" & aWord & """ is" & IIf(wordFound, "", " not") & " in this"
Next

解释:

  1. InStr(input, aWord) <> 0 为真或假。您将它分配给 wordFound。这是执行 If...Else 的更简洁的方法。 (这个想法的一个更简单的例子:x = 1 = 1 将设置 x 等于 True,而 x = 1 = 0 将设置 x 等于 false。你可以用括号更容易理解:x = (1 = 1)等)
  2. IIf ("instant if") 采用 IIf(condition, valueIfConditionIsTrue, valueIfConditionIsFalse) 的形式。
  3. 因为wordFound是一个布尔值,所以说wordFound和说wordFound = True是一样的,所以你可以省略= True(你也可以说Not wordFoundwordFound = False).
  4. 的含义相同

编辑:如果您希望您的聊天机器人在遇到任何一个词时回复 "that's great",请将 conversation() 从 Sub 更改为 Function 并 return true 或 false。像这样:

Private Function conversation(theInput As String) As Boolean
    Dim arrWords As String, aWord As String
    arrWords = Array("good", "great", "bad")

    'Get rid of your wordFound variable — you don't need it any more
    conversation = False
    For Each aWord In arrWords
        If InStr(theInput, aWord) > 0 Then
            conversation = True
        End If
    Next   
End Function

Private Sub SendButton_Click()
    If conversation(myChatTextBox.Text) 
        MsgBox "That's great!"
    Else
        MsgBox "That's not so great."
    End If
End Sub