4

我有一个简单的问题:vb.net 如何确定字符串长度并处理字符串的终止?
我知道C(及其系列)空字符是字符串的结尾。在 vb6 中,空字符对字符串的终止没有影响,但在 vb.net 中它似乎有雾!
假设 vb6 中的代码:

Private Sub Command1_Click()
Dim Str As String
Str = "Death is a good user," & Chr(0) & " Yes I'm good"
RichTextBox1.Text = Str
RichTextBox1.Text = RichTextBox1.Text & vbNewLine & Len(Str)
End Sub

当此代码运行时会发生以下情况: 在此处输入图像描述

而且没关系。这是类似的代码C

#include "stdafx.h"
#include <string.h> 
int main(int argc, char* argv[])
{
    char *p="Death is a good user,\0 Yes I'm good";

    printf("String:%s\nString length:%d\n",p,strlen(p));

    return 0;
}

这就是发生的事情:
在此处输入图像描述

根据规则,这也很好C,但这是 vb.net 中的相同代码:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim str As String = "Death is a good user," & Chr(0) & " Yes I'm good"
    RichTextBox1.Text = str
    RichTextBox1.Text &= vbNewLine & str.Length
End Sub

会发生什么:
在此处输入图像描述


这似乎不太对劲!

编辑1:写入文件似乎是正确的:

在此处输入图像描述

编辑 2Marktcarvin建议,这可能是 UI 的问题,但它没有解释为什么 vb6 显示整个字符串!

编辑 3:我知道 Windows 及其 API、UI、... 是用 编写的C,所以他们会做出类似的反应是正常的C,但正如我上面所展示的,他们没有。

4

2 回答 2

9

In VB.NET (and C#) strings are treated very similarly to how they are in VB6, and that is they have an explicit length that is not based on any particular character or characters contained within them.

In regards to the RichTextBox, it would simply appear that it does not support an embedded null character.

于 2012-11-27T22:27:37.853 回答
3

底层运行时支持库在您的代码片段中使用了 3 种不同的字符串类型:

  • BSTR,由 VB6 使用。它是所有 ActiveX 控件使用的 COM 自动化类型,可以存储 Unicode 字符串并包括显式长度。因此,BSTR 可以存储嵌入的零。
  • C 字符串,由 C 语言使用。没有存储显式长度,零表示字符串结束。winapi 是基于 C 的,并在其函数中使用 C 字符串。
  • System.String,.NET 字符串类型,用于任何 .NET 代码。与 BSTR 类似,它也有一个明确的长度字段,因此可以存储嵌入零的字符串。

在所有三种情况下,底层运行时支持库都需要使用互操作来使字符串可见:

  • VB6 为 RichEditBox 使用 ActiveX 控件。很难猜出该控件的确切外观,它非常特定于 VB6,并被命名为richtx32.ocx。它也使用原生 Windows Richedit 控件 (riched32.dll),因此 ActiveX 控件非常充当包装器,使原生 Windows 控件可在 VB6 应用程序中使用。您已经最终证明它尊重 BSTR 的行为并处理嵌入的零,就像任何 ActiveX 控件一样。

  • C 程序使用 C 运行时库,该库又通过调用 winapi 控制台函数 WriteConsole() 来实现 printf()。这个 api 函数是基于 C 的,但降压已经在 printf() 处停止,嵌入的零是该函数的字符串终止符。这里没有惊喜。

  • Winforms 程序使用 .NET RichEditBox 类,它是riched20.dll 本机 Windows 控件的托管包装。底层机制是 pinvoke,类的几乎所有属性和方法都是通过 pinvoking SendMessage() 来实现的,以发送消息,例如 EM_SETTEXTEX,该消息会更改控件显示的文本。这也是一个基于 C 的 api,零就像一个字符串终止符。与richtx32.ocx 包装器不同,.NET RichEditBox 包装器类不努力正确处理嵌入零的字符串。它只是按原样传递字符串并将其留给 pinvoke 编组器将 .NET 字符串转换为 C 字符串。除了在零处截断字符串之外别无选择,因为 C 字符串没有长度字段。

于 2012-12-06T23:36:33.773 回答