binary(3tcl)

NAME
binary - 从(向)二进制串插入和提取字段

总览 SYNOPSIS
binary format formatString ?arg arg ...?
binary scan string formatString ?varName varName ...?

描述 DESCRIPTION

 这个命令提供操纵二进制数据的设施。第一种形式是 binary format，从普通的 Tcl 值来建立一个二进制串。例如，给出值 16 和 22，可以产生一个8字节的二进制串，由两个4字节的整数组成。第二种形式是 binary scan，做相反的事: 从一个二进制串中提取出数据并作为通常的 Tcl 字符串值而返回。

二进制化 BINARY FORMAT

binary format 命令生成一个二进制串，其格式由 formatString 指定，它的内容来(自在后面)增添的参数。返回结果二进制值。

formatString 由零个或多个字段说明符(specifier)的序列组成，用零个或多个空格分隔。每个说明符都是一个单独的类型字符，跟随着一个可选的数值 count。多数字段说明符消耗(consume)一个参数来获取被格式化的值。类型字符指定如何格式化值。count 典型的指示从值中接受了多少个指定类型的单项(item)。如果count 存在，则是一个非负十进制整数或 *，星号通常指示使用在值中所有的单项。如果参数的个数不匹配在消耗参数的这些格式串中的字段的个数，则产生一个错误。

每个类型-数目(type-count)对在二进制串上移动一个假想的游标，在当前的位置上存储一些字节并且游标前进到最近存储的字节的紧后面。游标初始在位置 0 也就是在数据的开始(端)。类型可以是下列字符中的任意一个:

a   在输出串中存储长度是 count 的一个字符串。如果 arg 比 count 的字节数少，则有增补的零字节来填充字段。如果 arg 比指定长度多，忽略额外的字符。如果 count 是 *, 则格式化在 arg 中的所有字节。如果省略了 count ，则格式化一个字符。例如，
    binary format a7a*a alpha bravo charlie 将返回等价于 alpha\000\000bravoc的一个串。

A   除了使用空格而不是空字符来填充之外，这种形式同于 a。例如，
    binary format A6A*A alpha bravo charlie 将返回 alpha bravoc.

b   在输出串中存储 count 个二进制数字的一个串，并且在每个字节中以从低到高的次序(来排序)。Arg 必须包含一个 1 和 0 字符的一个序列。以从最先到最后的次序散布(emit)结果字节，并且以在每个字节中以从低到高的次序格式化每位。如果 arg 比 count 的位数少，则剩余的位使用零。如果 arg 比指定的位数多，忽略额外的位。如果 count 是 *, 则格式化在 arg 中所有的位。如果省略了 count，则格式化一位。如果如果格式化的位数不结束在字节边界上，最后的字节的剩余的位将是零。例如，
    binary format b5b* 11100 111000011010 将返回等价于 \x07\x87\x05的一个串。

B   除了在每个字节中以从高到低的次序(来排序)之外，这种形式同于 b。例如，
    binary format B5B* 11100 111000011010 将返回等价于 \xe0\xe1\xa0的一个串。

h   在输出串中存储 count 个十六进制的数字的一个串，并且在每个字节中以从低到高的次序(来排序)。Arg 必须包含在“0123456789abcdefABCDEF”(字符)集中的字符的一个序列。以从最先到最后的次序散布(emit)结果字节，并且在每个字节中以从低到高的次序格式化十六进制数字。如果 arg 比 count 的数字个数少，则剩余的数字使用零。如果 arg 比指定的数字的个数多，忽略额外的数字。如果 count 是 *，则格式化在 arg 中所有的数字。如果省略了 count ，则格式化一个数字。如果格式化的数字的个数不结束在一个字节的边界上，最后的字节的剩余的位将是零。例如，
    binary format h3h* AB def 将返回等价于 \xba\x00\xed\x0f的一个串。

H   除了在每个字节中以从高到低的次序(来排序)之外，这种形式同于 h 。例如，
    binary format H3H* ab DEF 将返回等价于 \xab\x00\xde\xf0的一个串。

c   在输出串中存储一个或多个8位整数值。如果未指定 count，则 arg 必须包含一个整数值；否则 arg 必须包含至少有一个整数元素的一个列表。在当前的位置上把每个整数的低位(low-order)的 8 位存储成一个一字节的值。如果 count 是 *，则格式化在列表中所有的整数。如果在列表中的元素的个数比 count 少，则产生一个错误。 如果在列表中的元素的个数比 count 多，则忽略额外的元素。例如，
    binary format c3cc* {3 -3 128 1} 260 {2 5} 将返回等价于 \x03\xfd\x80\x04\x02\x05 的一个串。而 binary format c {2 5} 将产生一个错误。

s   除了以小端(little-endian)字节序在输出串中存储一个或多个16位整数之外，这种形式同于 c。在当前位置上把每个整数的低位的16位存储成一个两字节的值，并且首先存储最低有效(significant)字节。例如，
    binary format s3 {3 -3 258 1} 将返回等价于 \x03\x00\xfd\xff\x02\x01 的一个字串。

S   除了以大端(big-endian)字节序在输出串中存储一个或多个16位整数之外，这种形式同于 s 。例如，
    binary format S3 {3 -3 258 1} 将返回等价于 \x00\x03\xff\xfd\x01\x02 的一个串。

i
     除了以小端(little-endian)字节序在输出串中存储一个或多个32位整数之外，这种形式同于 c。在当前位置上把每个整数的低位的32位存储成一个四字节的值，并且首先存储最低有效字节。例如，
    binary format i3 {3 -3 65536 1} 将返回等价于 \x03\x00\x00\x00\xfd\xff\xff\xff\x00\x00\x01\x00 的一个串。

I   除了以大端(big-endian)字节序在输出串中存储一个或多个32位整数之外，这种形式同于 i。例如，
    binary format I3 {3 -3 65536 1} 将返回等价于 \x00\x00\x00\x03\xff\xff\xff\xfd\x00\x01\x00\x00 的一个串。

f   除了以机器的本地表示在输出串中存储一个或多个单精度浮点数之外，这种形式同于 c。这种表示是不能跨体系移植的，所以不应用于在网络上交流浮点数。浮点数的大小在体系间可能不同，所以生成的字节数也可能不同。如果值溢出了机器的本地表示，则使用系统定义的 FLT_MAX 的值。因为 Tcl 在内部使用双精度浮点数，在转换成单精度时可能损失些精度。例如，运行在 Intel Pentium 处理器的一个 Windows 系统上，
    binary format f2 {1.6 3.4} 将返回等价于 \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 的一个串。

d   除了以机器的本地表示在输出串中存储一个或多个双精度浮点数之外，这种形式同于 f。例如，运行在 Intel Pentium 处理器的一个 Windows 系统上，
    binary format d1 {1.6} 将返回等价于 \x9a\x99\x99\x99\x99\x99\xf9\x3f 的一个串。

x   Stores count null bytes in the output string. If count is not specified, stores one null byte. If count is *, generates an error. This type does not consume an argument. For example,
    binary format a3xa3x2a3 abc def ghi 将返回等价于 abc\000def\000\000ghi 的一个串。

X   在输出串中反向移动游标 count 字节。如果 count 是 * 或比当前游标位置大，则游标定位到位置 0，这样下个存储的字节将是结果串中的第一个字节。如果省略了count，则游标反向移动一字节。 这种形式不使用参数。例如，
    binary format a3X*a3X2a3 abc def ghi 将返回 dghi.

@   在输出串中把游标移动到由 count 指定的绝对位置上。位置 0 参照在输出串中的第一个字节。如果 count 参照的位置超出至今所存储的最后的字节，则在空挡的(unitialized ?)位置上放置空字节并把游标放置到指定位置。如果 count 是 *，则游标将被移动到输出串的末端。如果省略了 count，则产生一个错误。这种类型不使用参数。例如，
    binary format a5@2a1@*a3@10a1 abcde f ghi j 将返回 abfdeghi\000\000j.

二进制检索 BINARY SCAN

binary scan 命令从一个二进制串分析字段、返回完成的转换的数目。String 给出要被分析的输入而 formatString 指示如何分析它。每个 varName 给出一个变量的名字；当从 string 检索出一个字段时，结果被赋给相应的变量。

如同 binary format 那样，formatString 由零个或多个字段说明符(specifier)的序列组成，用零个或多个空格分隔。每个说明符都是一个单独的类型字符，跟随着一个可选的数值 count。多数字段说明符消耗(consume)一个参数来获取检索出的值要放置在其中的那个变量。类型字符指定如何解释二进制串。count 典型的指定从数据中接受指定类型的多少个单项(item)。如果存在，count 是一个非负数的十进制整数或 *，星号通常指示要用到在数据中所有的剩余的单项。如果在满足当前字段说明符的当前位置之后没有剩下足够的字节，则相应的变量保持不动(untouch)而 binary scan 立即返回设置了的变量的个数。如果没有足够的参数给所有这些消耗参数的格式串中的字段，则产生一个错误。

着重 (important) 注意 c, s 和 S(还有在64位系统上的 i 和 II)将被检索成一个长整型 (long) 大小的值。在这种情况下，(最)高位设置(为1)的值(对于char 是 0x80，对于 short 是 0x8000，对于 int 是 0x80000000)，将被符号扩展。所以下列情况将发生: set signShort [binary format s1 0x8000] binary scan $signShort s1 val; # val == 0xFFFF8000 如果你打算生成一个无符号值，那么你可以把返回值屏蔽(mask)成需要的大小。例如，要生成一个无符号 short 值: set val [expr {$val & 0xFFFF}]; # val == 0x8000

每个类型-数目(type-count)对在二进制串上移动一个假想的游标，从当前的位置上读一些字节。游标的初始在位置 0 也就是数据的开始(端)。类型可以是下列字符中的任意一个:

a   数据是长度是 count 的一个字符串。如果 count 是 *，则在 string 中所有的剩余的字节将被检索到变量中。如果省略了 count，则将检索一个字符。例如，
    binary scan abcde\000fghi a6a10 var1 var2 将返回 1 并把等价于 abcde\000 的一个字符串存储到 var1 而 var2 保持不变。

A   除了在存储到变量之前从检索到的值中去除(strip)尾随的空白(blank)和空字符(null)之外，这种形式同于 a。例如
    binary scan "abc efghi \000" A* var1 将返回 1 并把 abc efghi 存储到 var1。

b   把数据转换成 count 位二进制数字的一个字符串，以从低到高的次序表示成“1”和“0”字符的一个序列。数据字节按从最先到最后的次序被检索，并且在每个字节中按从低到高的次序接受(每)位。忽略在最后的字节中的任何额外的位。如果 count 是 *，则检索在串中的所有的剩余的位。 如果省略了 count，则检索一位。例如，
    binary scan \x07\x87\x05 b5b* var1 var2 将返回 2 并把 11100 存储到 var1 且 1110000110100000 存储到 var2.

B   除了在每字节中按从高到低的次序接受(每)位之外，这种形式同于 b。例如，
    binary scan \x70\x87\x05 B5B* var1 var2 将返回 2 并把 01110 存储到 var1 且 1000011100000101 存储到 var2.

h   把数据转换成 count 个十六进制数字的一个字符串，以从低到高的次序表示成一个在 “0123456789abcdefABCDEF” (字符)集中的字符的一个序列。按从最先到最后的次序检索数据字节，并且在每个字节中以从低到高的次序接受十六进制数字。忽略最后的字节中的任何额外的位。如果 count 是 *, 则检索在串中所有剩余的十六进制数字。如果省略了 count，则检索一位十六进制数字。例如，
    binary scan \x07\x86\x05 h3h* var1 var2 将返回 2 并把 706 存储到 var1 且 50 存储到n var2.

H   除了在每个字节中以从高到低的次序接受数字之外，这种形式同于 h。例如，
    binary scan \x07\x86\x05 H3H* var1 var2 将返回 2 并把 078 存储到var1 且 05 存储到 var2.

c   把数据转换成 count 个8位有符号整数并作为一个列表存储到相应的变量中。如果 count 是 *，则检索在串中所有剩余的字节。如果省略了 count，则检索一个8位整数。例如，
    binary scan \x07\x86\x05 c2c* var1 var2 将返回2 并把 7 -122 存储到 var1 且 5 存储到 var2. 注意返回的整数是有符号的，但它们是类似下面这样的表达式来转换成无符号的8位数量(quantity): expr ( $num + 0x100 ) % 0x100

s   把数据解释成 count 个表示为小端字节序的16位有符号整数。 整数被作为一个列表存储到相应的变量中。如果 count 是 *，则检索在串中所有剩余的字节。如果省略了 count，则检索一个16位整数。例如，
    binary scan \x05\x00\x07\x00\xf0\xff s2s* var1 var2 将返回 2 并把 5 7 存储到 var1 且 -16 存储到 var2. 注意返回的整数是有符号的，但它们是类似下面这样的表达式来转换成无符号的16位数量(quantity): expr ( $num + 0x10000 ) % 0x10000

S   除了把数据解释成 count 个表示为大端字节序的16位有符号整数之外，这种形式同于 s。例如，
    binary scan \x00\x05\x00\x07\xff\xf0 S2S* var1 var2 将返回 2 并把 5 7 存储到 var1 且 -16 存储到 var2.

i   把数据解释成 count 个表示为小端字节序的32位有符号整数。 整数被作为一个列表存储到相应的变量中。如果 count 是 *，则检索在串中所有剩余的字节。如果省略了 count，则检索一个32位整数。例如，
    binary scan \x05\x00\x00\x00\x07\x00\x00\x00\xf0\xff\xff\xff i2i* var1 var2 将返回 2 ，并把 5 7 存储到 var1 且 -16 存储到 var2。注意返回的整数是有符号的并且不能被 Tcl 表示成无符号的值。

I   除了把数据解释成 count 个表示为大端字节序的32位有符号整数之外，这种形式同于 i。例如，
    binary \x00\x00\x00\x05\x00\x00\x00\x07\xff\xff\xff\xf0 I2I* var1 var2 将返回 2 ，并把 5 7 存储到 var1 且 -16 存储到 var2。

f   把数据解释成 count 个机器本地表示的单精度浮点数，把浮点数作为一个列表存储到相应的变量中 。如果 count 是 *，则检索在串中所有剩余的字节。如果省略了 count，则检索一个单精度浮点数。 浮点数的大小在体系间可能不同，所以检索的字节数也可能不同。如果数据不表示一个有效的浮点数，结果值是未定义的并且依赖于编译器。例如，运行在 Intel Pentium 处理器的一个 Windows 系统上，
    binary scan \x3f\xcc\xcc\xcd f var1 将返回 1，并把 1.6000000238418579 存储到 var1。

d   除了把数据解释成 count 个机器本地表示的双精度浮点数之外，这种形式同 于 f。例如，运行在 Intel Pentium 处理器的一个 Windows 系统上，
    binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f d var1 将返回 1 ，并把 1.6000000000000001 存储到 var11。

x   在 string 中正向移动游标 count 字节。如果 count 是 * 或比当前游标位置之后的字节数大，则游标定位到位置 string 中的最后一个字节之后。如果省略了count，则游标正向移动一字节。 注意 这种形式不消耗参数。例如，
    binary scan \x01\x02\x03\x04 x2H* var1 将返回 1，并把 0304 存储到 var1。

X   在 string 中反向移动游标 count 字节。如果 count 是 * 或比当前游标位置大，则游标定位到位置 0，这样下个检索的字节将是 string 中的第一个字节。如果省略了count，则游标反向移动一字节。 注意这种形式不消耗参数。例如，
    binary scan \x01\x02\x03\x04 c2XH* var1 var2 将返回 2，并把 1 2 存储到 var1 且 020304 存储到 var2。

@   在数据串中把游标移动到由 countt 指定的绝对位置上。位置 0 参照在 string 中的第一个字节。如果 count 参照的位置超出 string 的末端，则把游标定位在最后的字节的后面。如果省略了 count，则产生一个错误。例如，
    binary scan \x01\x02\x03\x04 c2@1H* var1 var2 将返回 2 ，并把 1 2 存储到 var1 且 020304 存储到 var2。

平台相关事宜 PLATFORM ISSUES
 有时希望以机器的本地字节序来格式化或检索整数值。参照 tcl_platform 数组中的 byteOrder 元素来决定在格式化或检索整数时使用那种类型字符。

参见 SEE ALSO
format(n), scan(n), tclvars(n)

关键字 KEYWORDS
binary, format, scan

[中文版维护人]
寒蝉退士

[中文版最新更新]
2001/06/21

《中国 Linux 论坛 man 手册页翻译计划》:
http://cmpp.linuxforum.net