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