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
您可能应该对您的其他文件执行类似的操作并获取另一个数组,然后比较这两个文件,或者您尝试对这两个文件执行的任何操作。
我正在使用 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
您可能应该对您的其他文件执行类似的操作并获取另一个数组,然后比较这两个文件,或者您尝试对这两个文件执行的任何操作。