问题
I want to write in a specific line in Textdocument but there´s a Problem with my code, i don´t know where the bug is.
set fp [open C:/Users/user/Desktop/tst/settings.txt w]
set count 0
while {[gets $fp line]!=-1} {
incr count
if {$count==28} {
break
}
}
puts $fp "TEST"
close $fp
The File only contains TEST. Has anybody an idea?
回答1:
You are using 'w' as access argument, which truncates the file. So you will loose all data from file while opening. Read more about open command
You can use 'r+' or 'a+'.
Also To write after a particular line you can move the pointer to the desired location.
set fp [open C:/Users/user/Desktop/tst/settings.txt r+]
set count 0
while {[gets $fp line]!=-1} {
incr count
if {$count==28} {
break
}
set offset [tell $fp]
}
seek $fp $offset
puts $fp "TEST"
close $fp
To replace a complete line it would be easier to do in following way. Rewrite all the lines and write new data on the desired line.
set fp [open C:/Users/user/Desktop/tst/settings.txt r+]
set count 0
set data [read $fp]
seek $fp 0
foreach line [split $data \n] {
incr count
if {$count==28} {
puts $fp "TEST"
} else {
puts $fp $line
}
}
close $fp
回答2:
With short text files (these days, short is up to hundreds of megabytes!) the easiest way is to read the whole file into memory, do the text surgery there, and then write the whole lot back out. For example:
set filename "C:/Users/user/Desktop/tst/settings.txt"
set fp [open $filename]
set lines [split [read $fp] "\n"]
close $fp
set lines [linsert $lines 28 "TEST"]
# Read a line with lindex, find a line with lsearch
# Replace a line with lset, replace a range of lines with lreplace
set fp [open $filename w]
puts $fp [join $lines "\n"]
close $fp
Doing it this way is enormously easier, and avoids a lot of complexities that can happen with updating a file in place; save those for gigabyte-sized files (which won't be called settings.txt
in any sane world…)
回答3:
package require fileutil
set filename path/to/settings.txt
set count 0
set lines {}
::fileutil::foreachLine line $filename {
incr count
if {$count == 28} {
break
}
append lines $line\n
}
append lines TEST\n
::fileutil::writeFile $filename $lines
This is a simple and clean way to do it. Read the lines up to the point where you want to write, and then write back those lines with your new content added.
回答4:
I'd suggest it would be easier to spawn an external program that specializes in this:
exec sed -i {28s/.*/TEST/} path/to/settings.txt
来源:https://stackoverflow.com/questions/37805957/tcl-tk-write-in-a-specific-line