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