为何VB表达式Asc(ChrB(128)&ChrB(0))返回63而非128?
为什么Visual Basic表达式
Asc(ChrB(128) & ChrB(0))返回63而非128? 核心原因是VB在处理ChrB拼接的字节序列时,会自动将其按系统默认ANSI编码(如Windows-1252)解码为Unicode字符,而128-159区间的部分字节无法映射为有效字符,最终被替换为问号?(ASCII码63)。
详细解释
- VB字符串的本质:VB中的字符串是UTF-16编码的Unicode字符串,每个字符固定占2字节。
ChrB(n)的作用是生成单个ANSI字节,而非Unicode字符。当你将两个ChrB返回的字节拼接时,VB会把这组字节视为ANSI编码的文本,尝试将其转换为Unicode——这个转换过程就是问题的根源。 - ANSI编码的映射限制:对于Windows默认的ANSI编码(Windows-1252),128-159区间的部分字节属于未定义或控制字符范畴。比如字节128,在Windows-1252中虽理论对应欧元符号
€,但早期VB版本对该映射支持存在问题;而像129、141这类字节属于控制字符,能被正确映射为对应的Unicode控制字符,因此Asc返回原值。当字节无法被ANSI编码识别时,VB会用替代字符?(ASCII 63)代替,这就是你看到的异常结果。 Chr(i)与ChrB(i) & ChrB(0)的差异:Chr(i)直接生成Unicode字符,当i在0-255时,对应Unicode的U+0000到U+00FF区间,因此Asc(Chr(i))必然返回i。ChrB(i) & ChrB(0)则是先构造ANSI字节序列,再经过ANSI→Unicode的转换,中间会丢失无法映射的字节信息。
解决方法
如果需要将字节值直接转换为对应的Unicode字符(U+00xx),应该使用ChrW函数,它直接操作Unicode字符,跳过ANSI编码的转换步骤:
' 正确返回128 Asc(ChrW(128))
如果是处理二进制数据,更推荐使用字节数组而非字符串,彻底避免编码转换带来的意外问题。
测试验证
你的测试代码中,160及以上的字节能正常返回原值,是因为这些字节在Windows-1252中都有对应的有效字符(比如160是不换行空格),能被正确转换为Unicode。
内容的提问来源于stack exchange,提问作者Ant
相关产品推荐
相关产品推荐

