TCL 读取结构化文件并将内容输入数组

TCL read in a structured file and enter contents into an array

我正在使用 TCL 读取以下格式的文件:

string1, 1.2 3.4

string2, 5.6 7.8

string3 等...

代码需要假设键的值在读取文件之前是未知的

我需要文件以数组结尾,以便与其他一些现有代码保持同步。

我试过了

array set FileA
set libDir "/tmp/"

set Datafile [open $libDir\Data.csv RDONLY]

set DataFileB [split $Datafile "\n"]

foreach line $DatafileB {

    [lappend FileA [split $line ","]]

)

## also tried:

while {![eof $Datafile]} {
    set DatafileB [string trim [gets $Datafile]]
    puts -nonewline "'$DatafileB'"
    if {$DatafileB == {}} {continue}
    puts "EMFLimits contents are $DatafileB "
    set FileA [split $DatafileB ","]
    foreach {i j} $FileA {}
    set key $i
    set val $j
    set FileAurrents [split [gets [open $libDir\EFM_CurrentLimit.csv RDONLY]]]
    if {[info exists FileA($key)]} {
        lappend FileA($key) $val
    } else {
        set FileA($key) [list $val]
    }
    }

我总是得到一个空数组?

我是 TCL 的新手,几周来一直被这个简单的谜题绊倒(在其他工作中)。

我不太明白你想做什么,但如果你想用你的文件内容填充一个数组,那么你的两次尝试都有一些问题。

您的第一次尝试:

array set FileA    ;# This should have raised an error without the empty list
array set FileA {} ;# You can create a new array like this
set libDir "/tmp/"

set Datafile [open $libDir\Data.csv RDONLY]

set DataFileB [split $Datafile "\n"]  ;# open creates a channel for the file. If you do 
                                       # puts $Datafile, you will see something 
                                       # like file225721ca0b0 instead of the actual 
                                       # contents, so you won't get anything useful here

set fileContents [read $Datafile] ;# This gets all the contents of the file

close $Datafile                   ;# Closing a channel after use is a good practice

set DataFileB [split $fileContents "\n"] ;# And now we split

foreach line $DataFileB {             ;# Variable names are case sensitive. Be consistent
    [lappend FileA [split $line ","]] ;# You cannot use lappend on an array. In Tcl, there
                                       # is a difference between arrays and lists. 
                                       # lappend essentially stands for list append. 
                                       # This line should raise an error

    # You can use a bit of the code you used in your second attempt:
    foreach {i j} [split $line ","] {}
    set key $i
    set val $j
    if {[info exists FileA($key)]} {
        lappend FileA($key) $val
    } else {
        set FileA($key) [list $val]
    }
} ;# How did this become a parenthesis? It should be a brace

parray FileA   ;# You can use this to pretty print the contents of the array

至于你的第二次尝试

while {![eof $Datafile]} {
    set DatafileB [string trim [gets $Datafile]]
    puts -nonewline "'$DatafileB'"
    if {$DatafileB == {}} {continue}
    puts "EMFLimits contents are $DatafileB "
    set line [split $DatafileB ","]  ;# FileA is an array you created. This line should 
                                      # raise an error because you are trying to overwrite 
                                      # the array with a "standard value". Use a different 
                                      # name. I will use line
    foreach {i j} $line {}
    set key $i
    set val $j
    set FileAurrents [split [gets [open $libDir\EFM_CurrentLimit.csv RDONLY]]] ;# You are 
            # not using this variable, so I don't know what you intend to do, but his line 
            # will continuously create new channels of the same file. You need to close 
            # channels after using them using close
    if {[info exists FileA($key)]} {
        lappend FileA($key) $val
    } else {
        set FileA($key) [list $val]
    }
}

close $Datafile
parray FileA

也就是说,我可能会写一些更像这样的东西:

array set fileA {}
set libDir "tmp"
set dataFile [open [file join $libDir Data.csv] r]
set fileContents [read $dataFile]
close $dataFile

foreach line [split $fileContents "\n"] {
    lassign [split $line ","] key val
    lappend fileA($key) $val          ;# lappend creates the variable if it does not 
                                       # already exists so it is pretty convenient
}

parray fileA

您可能应该对您的其他文件执行类似的操作并获取另一个数组,然后比较这两个文件,或者您尝试对这两个文件执行的任何操作。