从字符数组转换时的字符串长度

Jan*_*nis 4 .net vb.net arrays string

我遇到了严重的字符串处理问题.由于我的问题很难描述,我将从一些演示代码开始再现它们:

Dim s1 As String = "hi"
Dim c(30) As Char
c(0) = "h"
c(1) = "i"
Dim s2 As String = CStr(c)
s2 = s2.Trim()
If not s1 = s2 Then
   MsgBox(s1 + " != " + s2 + Environment.NewLine + _
          "Anything here won't be printed anyway..." + Environment.NewLine + _ 
          "s1.length: " + s1.Length.ToString + Environment.NewLine + _
          "s2.length: " + s2.Length.ToString + Environment.NewLine)
End If                    
Run Code Online (Sandbox Code Playgroud)

结果消息框如下所示:

消息框的屏幕截图仅显示hi!= hi但不显示文本的其余部分

这种比较失败的原因是s2的长度为31(来自原始数组大小),而s1的长度为2.

当从字节数组中读取字符串信息时,我经常偶然发现这种问题,例如,当处理来自MP3或具有预定长度的其他编码(ASCII,UTF8,...)信息的ID3Tag时.

是否有任何快速而干净的方法来防止这个问题?

将s2"修剪"为调试器显示的字符串的最简单方法是什么?

先谢谢,Janis

Ňɏs*_*arp 7

为清楚起见,我更改了变量名称:

Dim myChars(30) As Char
myChars(0) = "h"c           ' cannot convert string to char
myChars(1) = "i"c           ' under option strict (narrowing)
Dim myStrA As New String(myChars)
Dim myStrB As String = CStr(myChars)
Run Code Online (Sandbox Code Playgroud)

简短的回答是这样的:

在引擎盖下,字符串字符数组.最后两行都使用NET代码创建一个字符串,另一个是VB函数.问题是,虽然数组有31个元素,但只有2个被初始化:

在此输入图像描述

其余的是null/Nothing,这对于一种Char手段Chr(0)或者NUL.由于NUL用于标记的结束String,只有字符,直到达到其NUL 将在打印Console,MessageBox等等附加到字符串也不会显示文本.


概念

由于上面的字符串是直接从char数组创建的,因此长度是原始数组的长度.它Nul是有效的,char因此它们被添加到字符串中:

Console.WriteLine(myStrA.Length)     ' == 31
Run Code Online (Sandbox Code Playgroud)

那么,为什么不Trim删除空字符呢?MSDN(和Intellisense)告诉我们:

[Trim]从当前String对象中删除所有前导和尾随空白字符.

尾随null/Chr(0)字符不是Tab,Lf,Cr或Space等空格,而是控制字符.

但是,String.Trim有一个重载,允许您指定要删除的字符:

myStrA = myStrA.Trim(Convert.ToChar(0))
' using VB namespace constant
myStrA = myStrA.Trim( Microsoft.VisualBasic.ControlChars.NullChar)
Run Code Online (Sandbox Code Playgroud)

您可以指定多个字符:

' nuls and spaces:
myStrA = myStrA.Trim(Convert.ToChar(0), " "c)
Run Code Online (Sandbox Code Playgroud)

字符串可以作为char数组索引/迭代:

    For n As Int32 = 0 To myStrA.Length
        Console.Write("{0} is '{1}'", n, myStrA(n))  ' or myStrA.Chars(n)
    Next
Run Code Online (Sandbox Code Playgroud)

0是'h'1
是'我'
2是'

(输出窗口甚至不会打印尾随的CRLF.)但是,您无法更改字符串的char数组来更改字符串数据:

   myStrA(2) = "!"c
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为它们是只读的.

也可以看看:

ASCII表