二进制扫描"xyz" H* 有什么作用?



我看到以下代码:

binary scan  "xyz"  H* var

这让我感到困惑:binary scan应该扫描二进制流并构造字符串类型变量,但这里是"xyz"......?

我在 tclsh 中做了以下实验:

% puts $var
78797a    <== what is this?
% binary scan $var @1H y    <== I mean to get "y"
1
% puts $y     <== but I get "3"?
3

我迷路了。

你能解释一下这是怎么回事吗?

知道字符"x"的十六进制值是否0x78有帮助? 或者binary scan x78x79x7a H* var2与您的示例相同?我认为,"二进制扫描"手册页中"H"转换代码下的示例很好地解释了它。

在你的代码中:

binary scan  "xyz"  H* var

二进制字符串是xyz,它是三个字节,分别是xyz的 ASCII 值。然后,我们要求以大端顺序为var变量提供扫描字节的序列十六进制数字(这是处理字符串的正确做法,顺便说一句!),十六进制数字是二进制字符串中字节数的两倍(因为*)。让我们仔细检查一下文档的内容:

数据按从高到低的顺序转换为一串十六进制数字,表示为集合"0123456789abcdef"中的字符序列。数据字节按从头到尾的顺序扫描,十六进制数字在每个字节内按从高到低的顺序进行扫描。最后一个字节中的任何额外位都将被忽略。如果count*,则将扫描字符串中所有剩余的十六进制数字。如果省略计数,则将扫描一个十六进制数字。例如

binary scan x07xC6x05x1fx34 H3H* var1 var2

将返回207c存储在var1中,051f34存储在var2中。

现在,xyz有三个字节,所以78797a中有六个数字。前两个十六进制数字,78是 ASCII 版本的十六进制x(自己检查),同样用于797a.

当您执行以下操作时:

binary scan $var @1H y 

您将内部光标移动到字符串中,以8(因为从零开始的索引),x38的 ASCII 的字节,并且由于没有countH,它获得38的第一个十六进制数字(即3),并将其放入y变量中。

要实际检索y,您只需在原始二进制字符串上使用string indexstring range(因为所有Tcl的字符串命令都可以在二进制数据上正常工作)。或者,您可以使用string range将十六进制数字从var中取出,并binary format转换回来:

binary format H* [string range $var 2 3]

binary scanbinary scan的结果可能不是一个好主意。这样做是完全合法的,但结果不太可能说明问题。

最新更新