为啥这个 ASCII 字符输出为空字符串(VB.NET)?

Posted

技术标签:

【中文标题】为啥这个 ASCII 字符输出为空字符串(VB.NET)?【英文标题】:Why does this ASCII character output as empty string (VB.NET)?为什么这个 ASCII 字符输出为空字符串(VB.NET)? 【发布时间】:2013-02-20 05:11:27 【问题描述】:

我正在尝试将 ASCII 字符 131(ƒ - 带钩子的拉丁小写字母 f)输出到消息框,但由于某些奇怪的原因,它显示为空字符串。我有以下 VB.NET 代码:

Dim str As String = Convert.ToChar(131)
MessageBox.Show(str, "test", MessageBoxButtons.OK, MessageBoxIcon.Information)
Debug.Print(str)

在上面,消息框没有显示任何内容,但 debug.print 语句在“立即窗口”中正确显示了字符。我有大约 70 个其他 ascii 字符都可以使用这种方法正常工作,但只有少数几个显示为空白(131 和 EN 破折号 150)。

例如,以下工作:

str = Convert.ToChar(164)
MessageBox.Show(str, "test", MessageBoxButtons.OK, MessageBoxIcon.Information)
Debug.Print(str)

我也尝试转换为 UTF8,但我得到了与第一个代码 sn-p 中相同的行为:

Dim utf8Encoding As New System.Text.UTF8Encoding(True)
Dim encodedString() As Byte
str = Convert.ToChar(131)
encodedString = utf8Encoding.GetBytes(str)
Dim str2 As String = utf8Encoding.GetString(encodedString)
MessageBox.Show(str2, "test", MessageBoxButtons.OK, MessageBoxIcon.Information)
Debug.Print(str2)

这是编码问题吗?感谢您提供任何见解。

编辑:澄清一下,我实际上并没有尝试将字符输出到消息框。该代码只是一个测试。我试图将字符作为字符串传递给在第 3 方 xml 编辑器控件中使用它的函数,但它显示为空白。即使在 Visual Studio 中调试时,您也可以看到它的值等于 ""。

编辑 2:感谢下面接受的答案的一些调查,我发现我使用了错误的 unicode 字符。对于这个 f 字符,要使用的代码是 ToChar(402)。这非常有效。谢谢大家。

【问题讨论】:

字符“ƒ”不是 Ascii 字符。这可能相关也可能不相关。这个字符在不同的字符码中有不同的码号。 查看 vb.net 中的默认字体(MS Sans Serif)我看不到那个符号,粘贴到记事本并更改为 Sans Serif 符号显示为一个奇怪的字符,它可能是一个字体问题? MessageBox 使用默认的系统字体。如果默认系统字体中不存在该字符,则您将看不到该字符。您可以滚动自己的 MessageBox,或者查看Extended Message Box Library,它看起来允许您更改标准 MessageBox 上的字体(以及其他内容)。 Use Option Strict On! - 那么这段代码甚至无法编译。 @konrad-rudolph 我有它,它对我有用...你在哪里遇到错误? 【参考方案1】:

正如其他人所指出的,“ƒ”字符不是 ASCII 字符。 ASCII 严格来说是 7 字节格式,“扩展 ASCII”字符完全不同,具体取决于您引用的编码。例如,Windows CodePage 1250 的字符 131(0x83) 有一个空白,但 CodePage 1252 在该槽中具有“ƒ”字符。

我在下面的示例中使用 1252,但如果您要转换较大的编码 ASCII 文本主体,您应该确保正确识别正在使用的编码并使用正确的代码页进行转换。

我认为,处理这个问题的最佳方法是将所有内容都转换为 Unicode,并远离扩展的 ASCII,除非出于遗留原因绝对必要。但是,要获得“ƒ”字符,您可以执行以下操作:

Imports System.Text

然后:

Dim enc1252 As Encoding = Encoding.GetEncoding(1252)
Dim bArr(0) As Byte
bArr(0) = CByte(131)

Dim str2 As String = Encoding.Unicode.GetString( _
                     Encoding.Convert(enc1252, Encoding.Unicode, bArr))

MessageBox.Show(str2, " test", MessageBoxButtons.OK, _
                MessageBoxIcon.Information)

然而,VisualStudio 本身使用 Unicode,所以如果您只需要显示“ƒ”字符,而不需要实际转换任何旧文本,您总是可以这样做:

MessageBox.Show("ƒ", " test", MessageBoxButtons.OK, _
                MessageBoxIcon.Information)

【讨论】:

感谢您提供信息丰富的解决方案! (使用 1252 编码在我的上下文中工作,只需将硬编码字符传递给函数 not 工作) @http203 您使用的是哪个版本的 VisualStudio? @J 2008 目前。顺便说一句,我发现 ToChar(402) 正确输出了字符...... Visual Studio 使用什么代码页,我应该参考什么官方文档? @http203 这是因为 402(0x192) 是 ƒ 字符的 Unicode (UTF-8) 字节值。据我所知,VisualStudio 专门使用 Unicode(我认为 C++ 除外,您可以在项目设置中指定使用 ANSI)...我对为什么硬编码字符不使用感到有点困惑为你工作。如果您不需要转换正文(即:您只需要 ƒ),那么可以,您可以直接使用字符 402 并跳过转换路径。不过,您应该可以直接在 IDE 中使用 unicode... @J 好的,我调查过回答你的问题。当我在此处粘贴您的 f 字符时,它会进行硬编码。当我从 Debug.Print 语句的即时窗口中复制它时(来自 ToChar(131) 作为字符串的结果),它不起作用,因为它实际上是一个不同的字符。我把两个都复制到记事本里了,你的出现了,另一个没有。

以上是关于为啥这个 ASCII 字符输出为空字符串(VB.NET)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥角度表达式评估为属性中的空字符串

C语言ASCII码与字母如何转换?求详解

MFC中输出String类型(内容为01串)出现乱码

当默认编码为 ASCII 时,为啥 Python 会打印 unicode 字符?

为啥整型数组可以输入存储字符串,字符数组又可以输入存储整数?

为啥在反应形式中将空字符串设置为 null 变成空字符串