【问题标题】:Using Array with Instr将数组与 Instr 一起使用
【发布时间】:2018-08-18 09:40:07
【问题描述】:

我正在使用 VB6 创建一个聊天机器人,这个聊天机器人的全部基础是每当用户写一个“触发词”,例如“好”、“惊人”等,聊天机器人都会回复“那太好了” ”。 但是,每当我不写触发词时,只会出现“Word is in this”的msgbox,我不知道我做错了什么。我试过弄乱 >、

  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

【问题讨论】:

  • 请提供Minimal, Complete, and Verifiable example 并准确解释什么没有按预期工作以及您可能遇到的任何错误。
  • “但是,在编写触发词时,只会出现“Word is in this”的消息框” - 这听起来正是您想要的 - 一个消息框当触发词在输入中时,会说“词在其中”。
  • 但是,wordFound = True And MsgBox "Word is in this" 是一个语法错误。你的代码甚至没有运行。
  • 我的错,我会编辑问题。我的意思是,即使我写或不写触发词,msgbox“word is in this”也会出现。我试过弄乱 >、

标签: vb6


【解决方案1】:

其他答案已经解释了您的逻辑是倒退的,就是这样。

而且,我不知道您是否准确地复制了您的代码,但是当我将它复制到 VB 中时,我得到 - 正如我所料 - 带有 MsgBox 行的语法错误。我可以通过在MsgBox 参数中添加括号来“修复”这个问题,例如: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 返回零时,这意味着参数 2 中的字符串不在参数 1 中的字符串中。因此,这意味着“单词不在其中”,而不是那个它是。 (这就是您遇到的问题的答案;剩下的只是为了改进您的代码。)
  4. wordFound = True And MsgBox("Word is in this") 只是巧合。 MsgBox 在没有参数的情况下成功运行时返回值 1。 (谁知道?我不得不自己尝试一下。可能是因为它可以设置为针对不同类型的 ms 返回许多不同的值)所以你的逻辑是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。您可以使用括号使其更容易理解:@987654363 @等)
  2. IIf ("instant if") 采用 IIf(condition, valueIfConditionIsTrue, valueIfConditionIsFalse) 的形式。
  3. 因为wordFound是一个布尔值,所以说wordFound和说wordFound = True是一样的,所以你可以省略= True(你也可以说Not wordFoundwordFound = False意思一样)。

编辑:如果您希望聊天机器人在遇到任何单词时回复“太好了”,请将 conversation() 从 Sub 更改为 Function 并返回 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     

【讨论】:

    【解决方案2】:

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

      imput = UCase(imput)
    

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

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

    【讨论】:

    • @SelcouthTurner 这也是个好主意。它具有使输入不区分大小写的效果。
    • 在这种特殊情况下,OP 无论如何都不需要ElseIf。最好只使用Else,因为没有任何测试可以满足所有先前的条件。
    【解决方案3】:

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

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

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

    你想要的是这样的:

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

    “未找到”条件的平行是正确的。

    【讨论】:

      猜你喜欢
      • 2020-12-05
      • 1970-01-01
      • 2018-08-17
      • 2017-03-19
      • 2015-10-05
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多