如何将变量存储在文件中?
How can I store my variable in a file?
我正在使用 Tcl/Tk,我想在一个文件中存储几个变量。我已经储存了一些,但有一个抵抗力。你能解释一下为什么吗?
这是我的变量出现的过程,这些过程在三个不同的脚本中,由顶部的 "source" 声明链接:
在主脚本中
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."
}
}
我的变量是"genAvg"。是我无法存储在文件中的唯一变量,其他变量(在列表中)如 "testScores" 工作得很好。我曾尝试对 "genAvg" 使用相同的语法,但我不明白为什么它不起作用。
关于信息,脚本的主要目标是测试学生,将他们的结果存储在文件中,最后比较他们的综合平均水平。
更新
仔细观察发现:
wm protocol . WM_DELETE_WINDOW {
set ::goOn 1
if {[info exists user]} {
set fd [open users/$::user w]
puts $fd 0
foreach elt $::entryTestScores { puts $fd $elt }
foreach elt $::testScores { puts $fd $elt }
puts $fd [lindex $::pages $::page]
puts $fd $::bgColor
close $fd
}
exit
}
这个"write"在一个文件里是吧?
标题说的是How can I store my variable in a file?,但是看代码,我怀疑你的意思是read a file and put the内容到变量。考虑到这一点,我注意到 off-by-one 错误。在 proc readUserFile
中,在读取文件并将内容拆分为行列表 (data
) 后,您没有对第一行做任何事情(在索引 0 处,因为 TCL 是 zero-base-index 语言)。您的脚本第一次从 data
检索内容是:
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
试试这个:
set ::genAvg [lindex $data 0]
这是在黑暗中拍摄的,因为我没有看到代码中的任何地方显示您的脚本写入文件时的顺序。
更新
我刚刚注意到这一行:
set ::entryTestScores [lrange $data 1 $::nbTests] ;# Entry test scores stored from line 1 to line nbTest
评论说:
Entry test scores stored from line 1 to line nbTest
但是,为了得到第1行到第nbTests
行的考试成绩,命令必须是:
set ::entryTestScores [lrange $data 0 [expr $::nbTests - 1]]
此外,以下几行也需要进行类似的调整。
更新 2
我在你的更新中看到,没有写::genAvg
。要解决这个问题,而不是:
puts $fd $::bgColor
close $fd
这样做:
puts $fd $::bgColor
puts $fd $::genAvg ; # Insert this line
close $fd
我正在使用 Tcl/Tk,我想在一个文件中存储几个变量。我已经储存了一些,但有一个抵抗力。你能解释一下为什么吗? 这是我的变量出现的过程,这些过程在三个不同的脚本中,由顶部的 "source" 声明链接:
在主脚本中
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."
}
}
我的变量是"genAvg"。是我无法存储在文件中的唯一变量,其他变量(在列表中)如 "testScores" 工作得很好。我曾尝试对 "genAvg" 使用相同的语法,但我不明白为什么它不起作用。
关于信息,脚本的主要目标是测试学生,将他们的结果存储在文件中,最后比较他们的综合平均水平。
更新
仔细观察发现:
wm protocol . WM_DELETE_WINDOW {
set ::goOn 1
if {[info exists user]} {
set fd [open users/$::user w]
puts $fd 0
foreach elt $::entryTestScores { puts $fd $elt }
foreach elt $::testScores { puts $fd $elt }
puts $fd [lindex $::pages $::page]
puts $fd $::bgColor
close $fd
}
exit
}
这个"write"在一个文件里是吧?
标题说的是How can I store my variable in a file?,但是看代码,我怀疑你的意思是read a file and put the内容到变量。考虑到这一点,我注意到 off-by-one 错误。在 proc readUserFile
中,在读取文件并将内容拆分为行列表 (data
) 后,您没有对第一行做任何事情(在索引 0 处,因为 TCL 是 zero-base-index 语言)。您的脚本第一次从 data
检索内容是:
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
试试这个:
set ::genAvg [lindex $data 0]
这是在黑暗中拍摄的,因为我没有看到代码中的任何地方显示您的脚本写入文件时的顺序。
更新
我刚刚注意到这一行:
set ::entryTestScores [lrange $data 1 $::nbTests] ;# Entry test scores stored from line 1 to line nbTest
评论说:
Entry test scores stored from line 1 to line nbTest
但是,为了得到第1行到第nbTests
行的考试成绩,命令必须是:
set ::entryTestScores [lrange $data 0 [expr $::nbTests - 1]]
此外,以下几行也需要进行类似的调整。
更新 2
我在你的更新中看到,没有写::genAvg
。要解决这个问题,而不是:
puts $fd $::bgColor
close $fd
这样做:
puts $fd $::bgColor
puts $fd $::genAvg ; # Insert this line
close $fd