Форматирование Tcl: как отобразить несколько строк и столбцов с форматированием - PullRequest
0 голосов
/ 24 июня 2018

Мне нужно напечатать следующее на основе переменной 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 голосов
/ 24 июня 2018

Ключевое, что вам нужно здесь, это format.Отлично подходит для вывода текста в текстовой форме фиксированной ширины.Теперь написание элементов формата для строки format - это искусство (очень тесно связанное с выполнением того же для sprintf() в C), которого в наше время не хватает многим, но что-то вроде этого - то, чего вы хотите, если бы вы простовыполнение n == 4 case:

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?), Но это не так важно здесь.

...