【问题标题】:Tcl/Tk write in a specific lineTcl/Tk 写入特定行
【发布时间】:2016-06-14 07:45:48
【问题描述】:

我想在 Textdocument 的特定行中写入,但我的代码有问题,我不知道错误在哪里。

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

该文件仅包含 TEST。 有人有想法吗?

【问题讨论】:

  • 描述“问题”。从代码来看,您最终得到的文件似乎只包含 TEST,对吗?
  • @Jerry 是的,你说得对。该文件仅包含 TEST
  • 好的,如果行中已经有内容(在本例中为第 28 行),您要替换那里的内容还是添加到该行?

标签: tcl text-files data-manipulation


【解决方案1】:

对于短文本文件(现在,短文本文件高达数百兆字节!),最简单的方法是将整个文件读入内存,在那里进行文本手术,然后将全部内容写回。例如:

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

这样做非常容易,并且避免了在原地更新文件时可能发生的许多复杂性;将它们保存为千兆字节大小的文件(在任何理智的世界中都不会被称为settings.txt......)

【讨论】:

    【解决方案2】:

    您使用 'w' 作为访问参数,它会截断文件。因此,您将在打开文件时丢失文件中的所有数据。阅读有关open 命令的更多信息

    您可以使用“r+”或“a+”。

    还可以在特定行之后写入,您可以将指针移动到所需位置。

    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
    

    要替换完整的行,以下方式会更容易。重写所有行并在所需行上写入新数据。

    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 行。对不起,也许是我的错。我想用另一个替换孔线。
    • @ManInTheMiddle 更新答案
    • 中间不要使用a+进行更新;它设置一个操作系统级别的标志来强制写入总是在最后发生。 r+ 用于更新现有文件,但如果您要更改行中的字节数(或插入一行),那么您不妨重写整个文件。
    【解决方案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
    

    这是一种简单而干净的方法。将这些行读到您想写的地方,然后用您添加的新内容写回这些行。

    【讨论】:

    • Lewering 实际上我不能使用任何包,我必须以经典的 tcl 样式对其进行编码。
    【解决方案4】:

    我建议生成一个专门处理此问题的外部程序会更容易:

    exec sed -i {28s/.*/TEST/} path/to/settings.txt
    

    【讨论】:

      猜你喜欢
      • 2021-05-20
      • 2022-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-18
      • 1970-01-01
      相关资源
      最近更新 更多