【问题标题】:Comparing identical strings return false比较相同的字符串返回 false
【发布时间】:2016-12-18 20:35:36
【问题描述】:

我想编写一个检查我的 ip 的函数。如果我的 ip 是22.161.121.238 或检查给了Exception,它会休眠当前线程并再次开始检查。

代码如下:

Private Sub CheckIp()
    Dim ip As String
    Dim mine As String = "22.161.121.238"
    Try
        Do

        Using wc As New Net.WebClient

            ip = System.Text.Encoding.UTF8.GetString(wc.DownloadData("http://tools.feron.it/php/ip.php"))
        End Using


        If String.Equals(ip, mine) Then
            MessageBox.Show("2")
            Threading.Thread.Sleep(10000)
            Else
                MessageBox.Show("@" & ip & "@ is not equal to @" & mine & "@")
            End If
        End If

    Loop While ip = "22.161.121.238"


Catch ex As Exception
    Threading.Thread.Sleep(10000)
    CheckIp()

End Try

End Sub

我不知道为什么它不显示来自MessageBox 的“2”。即使ipmine 相同,它也不会启动Show 方法。你能告诉我为什么吗?

编辑

启动按钮后我得到的是(我添加了@ 以查看字符串的开始位置):

【问题讨论】:

  • 您如何确定ipmine 相同?我猜他们实际上不是。
  • 您或许应该考虑使用IpAddress 分类,它不会神奇地解决问题,但可以缓解问题(并且是一种更强大的做事方式
  • sstan,你不要像我一样启动 Visual Studio,复制代码并测试值,你的假设是完全错误的。
  • 我应该早点这样做,但我在第一篇文章中添加了一个 gif。

标签: .net vb.net io


【解决方案1】:

简单的答案是您的 2 个字符串相同。它们可能看起来相同,但您从网络资源返回的字符串在字符串开头包含 non visible Unicode Character 'ZERO WIDTH NO-BREAK SPACE' (U+FEFF)(我检查过)。

要确认,请检查返回字符串的各个字符的数值,特别是第一个字符。

作为一种解决方法,您可以使用@henry 的答案,它使用不同的比较字符串的方式,这将忽略u+feff 字符。

或者,您可以将其显式删除以进行相等性检查:

If String.Equals(ip.Replace(ChrW(&HFEFF), String.Empty), mine) Then

但是,如果您是 PHP 页面的作者,您可能希望对其进行修复,使其首先不返回 u+feff 字符。

【讨论】:

  • 这些类型的问题和答案如今很受欢迎 :-) 在过去几个月里已经回答了其中的一些问题 +1 btw
  • 因此,您必须使用 string.compare 函数:)
  • OP,不在乎它们是否在真正相等的定义中相等。
  • @henry:这就是你的解释。当我看到一个标题说:比较相同的字符串返回false,然后是你能告诉我为什么吗?,我认为正确的答案是因为字符串实际上并不相同。如果 OP 想要解决方法,好的。但我永远不想给任何人错误的印象,即String.Compare(s1, s2) == 0 是检查相同字符串的有效方法。
【解决方案2】:

试试这个函数,你原来的函数中有一些不正确的 if/then 逻辑。

Private Sub CheckIp()
Dim ip As String
Dim mine As String = "22.161.121.238"
Try
    Do

    Using wc As New Net.WebClient

        ip = System.Text.Encoding.UTF8.GetString(wc.DownloadData("http://tools.feron.it/php/ip.php"))
    End Using


    If string.Compare(ip, mine) = 0 Then
        MessageBox.Show("2")
        Threading.Thread.Sleep(10000)
    Else
            MessageBox.Show("@" & ip & "@ is not equal to @" & mine & "@")
    End If


Loop While ip.Contains("22.161.121.238") 


Catch ex As Exception
Threading.Thread.Sleep(10000)
CheckIp()

End Try

End Sub

【讨论】:

  • String.Equals 检查二进制相等性(这似乎是 OP 想要的),而 String.Compare 检查排序顺序并会受到当前文化的影响。
  • String.Equals 不比较引用(像大多数 Equals 一样),因为 String 是一个类 但是 具有“值类型行为”,所以 Equals 与 == operator
  • 为什么要否决我的答案,它是 100% 正确的。 Sstan,我在代码中测试了我的答案,您的评论完全错误地说明了 OP 想要什么。
  • String.Compare 可以返回 0 用于逻辑排序相同但不一定相等的 2 个字符串。这是怎么回事?
  • 好的,所以我们同意这两个字符串相同。我的问题是 OP 认为这两个字符串是相同的,并且 String.Equals 以某种方式损坏了。您的回答通过简单地说明他使用了错误的功能并隐晦地暗示Equals 没有按照他的想法做,进一步强化了这个错误的概念?您不认为解释他的代码为什么不起作用(字符串不相同)会更有用,这是 OP 的问题。然后,如果您想提出一个实用的解决方法,那么无论如何......
最近更新 更多