Tcl 如何将变量存储在文件中?

Tcl 如何将变量存储在文件中?,tcl,Tcl,我正在使用Tcl/Tk,我想在一个文件中存储几个变量。我已经储存了一些,只有一个。你能解释一下为什么吗? 以下是我的过程,其中显示了我的变量,这些过程在三个不同的脚本中,通过顶部的“源”声明链接: 在主脚本中 proc loginCreate { name } { if {[file exists users/$name] == 1} { set answer [tk_dialog .dialog "Username already existing" "This username al

我正在使用Tcl/Tk,我想在一个文件中存储几个变量。我已经储存了一些,只有一个。你能解释一下为什么吗? 以下是我的过程,其中显示了我的变量,这些过程在三个不同的脚本中,通过顶部的“源”声明链接:

在主脚本中

proc loginCreate { name } {
if {[file exists users/$name] == 1} {
    set answer [tk_dialog .dialog "Username already existing" "This username already exists. Do you want to log in as $name?" \
        question 1 Cancel "Log in"]
    if {$answer == 0} {return} else {
        loginValid $name
        set ::goOn2 1
    }
}
set ::user $name
set ::entryTestScores {"Not Taken" "Not Taken" "Not Taken" "Not Taken" "Not Taken" "Not Taken" "Not Taken" "Not Taken"\
"Not Taken" "Not Taken" "Not Taken"}
set ::testScores {"Not Taken" "Not Taken" "Not Taken" "Not Taken" "Not Taken" "Not Taken" "Not Taken" "Not Taken"\
"Not Taken" "Not Taken" "Not Taken"}
setColor khaki
onSelect 0
set ::genAvg 0
set ::goOn2 1
}
在另一个脚本中

proc readUserFile { name } {
    if {[file exists users/$name] == 0} {return -1}
    set ::user $name
    set fd [open users/$name r]
    set data [split [read $fd] \n]
    close $fd
    set ::entryTestScores [lrange $data 1 $::nbTests] ;# Entry test scores stored from line 1 to line nbTest
    set ::testScores [lrange $data [expr $::nbTests+1] [expr 2*$::nbTests]] ;# Individual test scores stored from line nbTest to line 2*nbTest
    if {[llength $data]>[expr 2*$::nbTests +2] && [lindex $data [expr 2*$::nbTests +2]] != ""} { ;# Colour name stored line 2*nbTest+2
        setColor [lindex $data [expr 2*$::nbTests +2]]
    } elseif {[lindex $data [expr 2*$::nbTests +2]] == ""} {
        setColor khaki
    } else {
        setColor khaki
    }
    onSelect [lsearch $::pages [lindex $data [expr 2*$::nbTests +1]]] ;# Page active to save stored line 2*nbTest+1
    set ::genAvg [lindex $data [expr 2*$::nbTests +3]] ;# General average of individual tests stored line 2*nbTest+3
    return 0
}
在第三个脚本中

proc DisplayResults {} {
    set linetag ""
    .fr.txt configure -state normal
    if {[info exist ::user]} {
        .fr.txt insert end "The best scores of $::user are:\n"
        for {set ind 0} {$ind < $::nbTests} {incr ind} {
            .fr.txt insert end \n
            incr ind
            .fr.txt insert end "\tTest #$ind\t" $linetag
            incr ind -1
            switch [lindex $::testScores $ind] {
                "Not Taken" { .fr.txt insert end "--/10\t\t" $linetag}
                10 { .fr.txt insert end "10/10\t\t" right$linetag}
                default { .fr.txt insert end "[lindex $::testScores $ind]/10\t" $linetag}
            }
        }
        if {[lsearch $::testScores "Not Taken"] == -1} {
            set mean [expr {double(round(100*[getAvg $::testScores]))/100}] ;# return the average rounded to 2 decimals
            set ::genAvg [lreplace $::genAvg 0 0 $mean] 
            .fr.txt insert end "\n\n\tYour general average is:\n\t $mean/10\n\n"
        } else {
            .fr.txt insert end "\n\nWhen you pass all the Individual Tests, your general average will be displayed here\n\n"
        }   
    } else {
        .fr.txt insert end "You are currently running on a generic profile, please log in to remember your high scores."
    }
}

“写入”文件不是吗?

标题说如何将变量存储在文件中?,但看看代码,我怀疑您的意思是读取文件并将内容放入变量中。考虑到这一点,我注意到一个接一个的错误。在proc
readUserFile
中,在读取文件并将内容拆分为行列表(
data
)后,您没有对第一行做任何操作(在索引0处,因为TCL是一种零基索引语言)。脚本第一次从
数据中检索内容是:

    set ::entryTestScores [lrange $data 1 $::nbTests] ;# Entry test scores stored from line 1 to line nbTest
请注意,
lrange
命令将索引1带到
$::nbTest
。这意味着不使用索引0处的数据。这可能是
::genAvg
的值吗?如果是这种情况,请不要:

    set ::genAvg [lindex $data [expr 2*$::nbTests +3]] ;# General average of individual tests stored line 2*nbTest+3
        puts $fd $::bgColor
        close $fd
试试这个:

    set ::genAvg [lindex $data 0]
这是瞎猜,因为我在代码中看不到任何地方显示脚本写入文件时的顺序

更新 我只是注意到在这一行:

    set ::entryTestScores [lrange $data 1 $::nbTests] ;# Entry test scores stored from line 1 to line nbTest
评论说:

从第1行到第2行存储的入学考试分数

但是,为了获得从第1行到第
nbTests
行的测试分数,命令必须是:

    set ::entryTestScores [lrange $data 0 [expr $::nbTests - 1]]
此外,以下行也需要进行类似的调整

更新2 我在您的更新中看到,没有编写
::genAvg
。要解决此问题,请执行以下操作:

    set ::genAvg [lindex $data [expr 2*$::nbTests +3]] ;# General average of individual tests stored line 2*nbTest+3
        puts $fd $::bgColor
        close $fd
这样做:

        puts $fd $::bgColor
        puts $fd $::genAvg    ; # Insert this line
        close $fd

标题说如何将变量存储在文件中?,但看看代码,我怀疑您的意思是读取文件并将内容放入变量中。考虑到这一点,我注意到一个接一个的错误。在proc
readUserFile
中,在读取文件并将内容拆分为行列表(
data
)后,您没有对第一行做任何操作(在索引0处,因为TCL是一种零基索引语言)。脚本第一次从
数据中检索内容是:

    set ::entryTestScores [lrange $data 1 $::nbTests] ;# Entry test scores stored from line 1 to line nbTest
请注意,
lrange
命令将索引1带到
$::nbTest
。这意味着不使用索引0处的数据。这可能是
::genAvg
的值吗?如果是这种情况,请不要:

    set ::genAvg [lindex $data [expr 2*$::nbTests +3]] ;# General average of individual tests stored line 2*nbTest+3
        puts $fd $::bgColor
        close $fd
试试这个:

    set ::genAvg [lindex $data 0]
这是瞎猜,因为我在代码中看不到任何地方显示脚本写入文件时的顺序

更新 我只是注意到在这一行:

    set ::entryTestScores [lrange $data 1 $::nbTests] ;# Entry test scores stored from line 1 to line nbTest
评论说:

从第1行到第2行存储的入学考试分数

但是,为了获得从第1行到第
nbTests
行的测试分数,命令必须是:

    set ::entryTestScores [lrange $data 0 [expr $::nbTests - 1]]
此外,以下行也需要进行类似的调整

更新2 我在您的更新中看到,没有编写
::genAvg
。要解决此问题,请执行以下操作:

    set ::genAvg [lindex $data [expr 2*$::nbTests +3]] ;# General average of individual tests stored line 2*nbTest+3
        puts $fd $::bgColor
        close $fd
这样做:

        puts $fd $::bgColor
        puts $fd $::genAvg    ; # Insert this line
        close $fd


您试图将
genAvg
存储在代码的何处?同意mkrieger1。genAvg没有写入任何地方,而且它在第一个过程中声明为
0
,然后在后续过程中作为列表处理。可能是个错误?我不知道mkreiger1,我在继续其他人的工作。所有与文件中存储的变量有关的内容都在这里。我试着把{set::genAvg$mean}放进去,但它也不起作用。@PiXieBulles如果你只想把
genAvg
中包含的值写在文本区域中,使用
.fr.txt insert end“genAvg的值是:$::genAvg”
不,我想把变量放在一个文件中(用户的结果存储在那里).您试图将
genAvg
存储在代码的何处?同意mkrieger1。genAvg没有写入任何地方,而且它在第一个过程中声明为
0
,然后在后续过程中作为列表处理。可能是个错误?我不知道mkreiger1,我在继续其他人的工作。所有与文件中存储的变量有关的内容都在这里。我试着把{set::genAvg$mean}放进去,但它也不起作用。@PiXieBulles如果你只想把
genAvg
中包含的值写在文本区域中,使用
.fr.txt insert end“genAvg的值是:$::genAvg”
不,我想把变量放在一个文件中(用户的结果存储在那里).不使用第一个索引是原编写者的选择。通过将::genAvg放在索引0处,不会改变任何东西。而且,我需要将变量添加到包含结果的文件中(以便对不同的用户进行排序)。那么,第一行包含什么?另外,您提到“我需要将变量添加到文件中”,但我没有看到将这些变量写入文件的任何代码。您没有显示相关代码,这使我们很难提供帮助。第一行不包含任何内容,它未被使用。即使有更新的问题,也没有代码来写东西?我在更新中看到了写入文件的代码。非常感谢。顺便说一下,第一行包含一个零。不使用第一个索引是原始写入程序的选择。通过将::genAvg放在索引0处,不会改变任何东西。而且,我需要将变量添加到包含结果的文件中(以便对不同的用户进行排序)。那么,第一行包含什么?另外,您提到“我需要将变量添加到文件中”,但我没有看到将这些变量写入文件的任何代码。您没有显示相关代码,这使我们很难提供帮助。第一行不包含任何内容,它未被使用。即使有更新的问题,也没有代码来写东西?我在更新中看到了写入文件的代码。非常感谢。顺便说一下,第一行包含一个零。