TCL格式设置:如何使用格式显示多行和多列

时间:2018-06-23 21:06:25

标签: scripting tcl

我需要根据变量n打印以下内容。

示例:如果n = 2 我需要打印:

1. -3 0
2.  3 0
3.  0 -3
4.  0 3

如果n = 3 我需要打印:

1. -3 0 0   
2. 3  0 0
3. 0 -3 0
4. 0  3 0
5. 0  0 -3
6. 0  0 3

如果n = 4,我需要打印:

1. -3 0 0 0
2. 3 0 0 0
3. 0 -3 0 0
4. 0 3  0 0 
5. 0 0 -3 0
6. 0 0 3  0
7. 0 0 0 -3
8. 0 0 0  3

1 个答案:

答案 0 :(得分:1)

您这里需要的关键是format。这对于以固定宽度的文本形式生成输出非常有用。现在,为format字符串编写格式项是一门艺术(与在C语言中对sprintf()进行相同操作非常相关),如今很多人都缺乏这种艺术,但是您却需要这样做只是想做n == 4案例:

puts [format "%d. %2d %2d %2d" $count $c1 $c2 $c3]

但是,在这种情况下,您遇到了一个更复杂的问题,因为您拥有可变数量的字段。这使事情变得棘手。您最好是借助一个过程来进行单行格式化,以逐步构建这些东西:

proc generateLine {n i} {
    set line [format "%d." $i]
    for {set x 1} {$x <= $n} {incr x} {
        # Double-ternary conditional operator
        set v [expr {$i == $x*2-1 ? -3 : $i == $x*2 ? 3 : 0}]
        append line [format " %2d" $v]
    }
    return $line
}

现在我们有了,程序的其余部分就足够简单了:

# Assume that the n variable has been set already
for {set i 1} {$i <= $n*2} {incr i} {
    puts [generateLine $n $i]
}

在编程中经常会发生,最简单的方法是将一个程序分成几部分,并在它们之间有合理的界限。知道在哪里拆分是您在经验上比较擅长的事情,但是如果您可以给拆分后的部分取一个明智的名称,那么拆分通常会在正确的位置。例如,上面我看到我想为每行做一些工作,并需要遍历所有需要的行;那是很明显的地方,可以分解并进行操作,generateLine。外部也很容易命名(也许是generateListOfLines?),但这在这里并不重要。