字符看起来像ASCII 63,但实际上不是,所以我无法删除它。

6
我正在读取一个文本文件中的文本。第一个要读取的字符串是 "Algood ",请注意空格。在记事本中,这个字符串看起来有一个空格,但实际上没有。当我在 Visual Studio 的 QuickWatch 中测试第六个字符(零基索引)时,它显示为:
"�"c

当我使用Asc函数获取ASCII码时,它告诉我ASCII码是63。63是一个问号。但当我测试字符串是否包含ASCII 63时,测试结果为false。因此,该字符串包含ASCII代码为63的字符,但实际上不是问号,而是其他字符,该字符测试为ASCII代码63。这是一个问题:如果我不知道如何称呼该字符,就无法删除该字符。我可以删除最后一个字符,但文本文件中并非每个字符串都包含该字符。
问题是:如果不是问号,那么这个字符是什么,我如何唯一地识别它以便我可以删除它?

3
使用AscW函数获取Unicode值。 - Raymond Chen
嗯,既然你没有发布文件,我们就无法告诉你它是什么了……打开十六进制编辑器以确保。问号符号出现的原因是字符不在字体之内。 - Brad
@RaymondChen,当我尝试使用AscW评估字符时,它显示“无法转换为整数”。 - Lou
只要我知道如何删除它,我就很开心。这解决了我的问题 - 如果你想把它作为答案,我可以接受 :)。 - Lou
3个回答

7

这是Unicode替换字符,U+FFFD,也称为ChrW(&HFFFD)

永远不要使用Asc()或Chr(),它们是不支持Unicode的VB6函数。将一个花式的Unicode码点传递给Asc()总是会产生63,即"?"c的字符代码,也就是说"我不知道你在说什么"。与"�"c相同的想法,只是使用了一个ASCII码而已。

看到黑色死亡钻石总是不好的消息,这意味着当字符串从底层字节值转换时出现了问题。因为一些字节值没有产生有效的字符。这正是您真正应该寻找的,您始终希望避免GIGO。垃圾进垃圾出是一个丑陋的数据损坏问题,没有赢家,只有受害者。你。


我正在编写一次性代码,我不会深入挖掘。尽管如此,您的答案已经解决了我的问题,所以我很高兴 :)。 - Lou
另外,在ChrW(&HFFFFD)中,您多了一个额外的F,我认为它应该是ChrW(&HFFFD)(这就是您最初写的方式)。 - Lou
1
当然,这里至少有6个可能出错的地方,其中3个不受您控制。最后两个是最可疑的,文本文件并不擅长知道文本的编码方式。除非它有一个BOM,但通常会缺失。同时也要考虑服务器端的问题 :) - Hans Passant
6个地方?你能详细说明一下吗,这很有趣。 - Lou
2
服务器端:文本文件 => 数据库 => Web 服务器。客户端:互联网 -> 浏览器 => 文本文件 => 您的应用程序。您可以轻松添加更多内容,将数据从一种格式转换为另一种格式会让很多程序员忙碌。 - Hans Passant
显示剩余2条评论

2
我已经在Excel VBA中编写了以下函数,它将删除单个单元格中的“黑色菱形”。
最难的事情是不要循环查找所有字段中的每个数字以找到它。我需要一种方法来识别黑色菱形而不检查所有字段的所有数字。
我使用了ADODB记录集,如果字符串被RS拒绝,则表示它包含无效字符。然后它会查找ASC(63)=“?” ,然后将单元格裁剪到没有黑色菱形。
这个方法可行的原因是当它遍历字符串中的每个数字时,它会将黑色菱形识别为ASC = 63。如果是真正的问号,它将被RS接受。
Private Function Correct_Black_Diamond(ByVal First_Address As Variant) As String
    Dim CheckDigit As Integer
    Dim Temp_string As String
    Dim temp_Rs As New ADODB.Recordset
        temp_Rs.Fields.Append "address", adChar, 9999
        temp_Rs.Open

        temp_Rs.AddNew
            On Error GoTo Further_Address_Check
            temp_Rs!Address = First_Address
        temp_Rs.Update

        Correct_Black_Diamond = First_Address
    Exit Function

Further_Address_Check:
        For CheckDigit = 1 To Len(First_Address)
            If Asc(Mid(First_Address, CheckDigit, 1)) = 63 Then
                Temp_string = Trim(Mid(First_Address, 1, CheckDigit - 1)) & Trim(Mid(First_Address, CheckDigit + 1, Len(First_Address)))
            End If
        Next CheckDigit
        First_Address = Temp_string
        Correct_Black_Diamond = First_Address
        Exit Function

End Function

0

使用:

LDM_MSG.Replace(ChrW(8203), "") 

改为:

LDM_MSG.Replace(Chr(63), "")

它解决了这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接