我正在努力将一些旧的VB6代码迁移到C#,我一直在针对VB代码测试我的C#代码,以检查每种语言中的对应方法是否返回相同的值。 / p>
我对此if语句有疑问:
If InStr(1, "LPTVJY", strTempTaxCode) <> 0 Then
strTempTaxCode = "0" & strTempTaxCode
End if
strTtempTaxCode = ""
从1
电话返回InStr(1, "LPTVJY", strTempTaxCode)
的值。为什么是这样?据我所知,我应该返回0
,因为"LPTVJY"
中的所有字符都不在strTempTaxCode
答案 0 :(得分:1)
非零长度的所有字符串,包括单字符字符串,都包含空字符串。
Debug.Print InStr("abc", "") ' => 1
Debug.Print InStr("a", "") ' => 1
Debug.Print "abc" & "" = "abc" ' => True
如果您无法理解概念,请考虑所有数字都是1:
' (not a real function)
Debug.Print Factors(2) ' => 1, 2
Debug.Print 2 * 1 = 2 ' => True
这称为 Multiplicative Identity Property 。您可以将字符串视为具有涉及空字符串的类似标识属性。
如果您不希望InStr()
匹配空字符串,请在调用之前进行初步测试:
If Len(strTempTaxCode) > 0 Then
If InStr(1, "LPTVJY", strTempTaxCode) <> 0 Then
strTempTaxCode = "0" & strTempTaxCode
End If
End If
答案 1 :(得分:0)
在VB中,字符串是基于1的。因此,当省略时, start 的默认值(要搜索的起始位置)为1.
当 string2 (你搜索的那个)长度为零或没有时,InStr返回 start * 1),这是你的案例1。
* 1) MSDN documentation on InStr
短语,因为"LPTVJY"
中的所有字符都不在strTempTaxCode
中,这表示您误解了该功能。它在string1中搜索string2。文档提到了很多边缘情况以及该情况下函数返回的内容。但是,该函数可能比这简单得多,可以写成嵌套循环,大致如下(只在内部进行了更优化)。
For s = start to Len(string1) - start
For c = 1 to Len(string2)
' Out of characters. There is no match.
If c+s-1 > Len(string1) then Return 0
' Mismatch. Try again for the next value of 's'.
If SubStr(string1, c+s-1) <> SubStr(string2, c) then Exit For
Next
Next
' If you get here, a match is found at position s.
Return s
请将上面的代码视为伪代码。它只是为了解释,我不知道它是否真的有效。
答案 2 :(得分:0)
之所以会这样,是因为根据Microsoft documentation,如果要搜索的字符串(即strTempTaxCode
)的长度为零,则该函数的返回值为可选的start
参数(即开始搜索的索引,在这种情况下将省略)。省略时,其值 NOT 不一定为1,但要搜索的字符串中的第一个字符位置(恰好为1,作为{中的第一个字符位置{1}}顺便说一句。
不会会发生这种情况是因为所有非零长度的字符串(包括单字符字符串)都包含空字符串或以下事实:正如其他人所指出的那样,"LPTVJY"
参数为1 ,因为它们不是,不是。要测试此效果,请尝试运行:
start
不幸的是,如果第二个字符串不为空(这将引发错误5:“无效的过程调用或参数”),则此方法将不起作用,但足以证明在以下情况下函数的返回值:要搜索的零长度字符串与它们包含在要搜索的字符串中,或者Debug.Print InStr(2, "abc", "") ' Returns 2, i.e. the start position
Debug.Print InStr(-13, "abc", "") ' Returns -13, i.e. the start position
Debug.Print InStr(-1, "abc", "") ' Returns -1, i.e. the start position
Debug.Print InStr(0, "abc", "") ' Returns 0, i.e. the start position
Debug.Print InStr(2, "", "") ' Returns 0, i.e. the first character position in ""
的值默认为1无关,而是与结果为 every 无关。 em> start
参数的值是(即使在最后一个测试用例中,由于要搜索的空字符串中的第一个字符位置也是0,因此它也被强制为0)。
最快的解决方案可以是:
•对于start
语句,请使用附加条件,例如指出的Bond:
if..then..else
•对于分配语句,创建一个UDF(用户定义函数)来处理它:
If Len(strTempTaxCode) > 0 And InStr(1, "LPTVJY", strTempTaxCode) > 0 Then
strTempTaxCode = "0" & strTempTaxCode
End if`
其他提出的解决方案速度较慢。上面这两个中的第一个在0.03 s内运行了100万次,与单条件Public Function InString(Optional startposition As Long = 1, Optional searchinto As String = "", Optional searchfor As String = "", Optional comparisonmethod As VbCompareMethod = vbBinaryCompare) As Long
If Len(searchfor) < 1 Then InString = -1 Else InString = InStr(startposition, searchinto, searchfor, comparisonmethod)
End Function
相同,而第二个在0.30 s内运行。如您所见,仅因为Microsoft认为即使明显InStr
包含在start
之类的字符串中,""
仍不,它仍应返回"LPTVJY"
值,用户有时必须使用比原始功能慢10倍的UDF。有趣的是,就像谎言在重复多次后变成真相一样,有些人甚至认为这是应该的,因为那是它的实现方式。