通过Tcl中的数据字读取文件数据字

时间:2014-03-25 16:18:19

标签: tcl

我想在Tcl中读取包含ASCII字符(常规文本文件,用于我们的目的)的文件,并将其逐字逐句(即数据字的数据字,每个数据字32位)存储为十六进制。 / p>

示例是包含以下内容的文本文件:

ÿÿÿÿûûûûÿÿÿÿ    

(以ASCII字符,ÿ = FF,û = FB)

我想把它解析成一个数组,结果是

[["FFFFFFFF"], ["FBFBFBFB"], ["FFFFFFFF"]]

我如何实现这一目标?我似乎无法找到合适的功能。

2 个答案:

答案 0 :(得分:3)

要获取数据,请使用以下内容:

set f [open theFile.txt]
set data [gets $f]
close $f

请注意,对于这类工作,我考虑将该文件用作二进制数据:

set f [open theFile.bin "rb"]
set data [read $f 12]
close $f

解析/转换

将数据解释为十六进制序列(小写)很容易:

binary scan $data H8H8H8 word(1) word(2) word(3)

将值存储到名为word关联数组中(索引为123)。如果您想要使用其他语言中习惯的内容,那么您可以转换为这样的Tcl列表:

set wordList [list $word(1) $word(2) $word(3)]

Tcl的列表值是真正的一等值。关联数组不是,而是命名实体,因此我们可以在binary scan中使用它们。

使用

完成上述操作后,您可以在列表中查找:

# *Zero*-based indexing is the rule in Tcl
lindex $wordList 0

用以下内容迭代它们:

foreach item $wordList { puts $item }

案例转换

如果您确实需要大写十六进制,请像这样应用string toupper

# Nasty type-shimmering trick!
set wordList [string toupper $wordList]

或者在Tcl 8.6中,你可以做这个更好的版本:

set wordList [lmap item $wordList {string toupper $item}]

但是我 只是string toupper因为我在正常情况下使用了这个值。

puts "[lindex $wordList 0] -> [string toupper [lindex $wordList 0]]"

答案 1 :(得分:2)

您可以使用scanformat,如下所示:

set asc "ÿÿÿÿûûûûÿÿÿÿ"
set result ""
set bytearray [list]
set count 0

foreach l [split $asc ""] {
    append result [format %x [scan $l %c]] ;# %c for reading character as unicode
                                            # %x for converting into hex
    incr count
    if {$count == 4} {
        set count 0
        lappend bytearray [string toupper $result]
        set result ""
    }
}

puts $bytearray
# => FFFFFFFF FBFBFBFB FFFFFFFF