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

跋
本頁面中文版由中文 man 手冊頁計劃提供。
中文 man 手冊頁計劃：https://github.com/man-pages-zh/manpages-zh