- format formatString ?arg arg ...?
Tcl 8.5 doc at: http://purl.org/tcl/home/man/tcl8.5/TclCmd/format.htm
Tcl 8.6 doc at: http://purl.org/tcl/home/man/tcl8.6/TclCmd/format.htm
LV The man page for 8.4 is missing examples. 8.5 is better, but I'm looking for an example of the following. I have a report line that I am trying to fill out. It consists of a time stamp, a date stamp, and 2 text strings. each of these items must begin in a specific column.
Note that format, by default, doesn't provide a way to use one of the number formats (like %d, etc.) AND specify a maximum number of digits. You could specify the format as a %s and then provide a maximum number of characters, or you could write tcl code to check for maximum. Jonathan Bromley posted, on comp.lang.tcl during early Sep 2007, this code, which provides a first cut at a "-strict" initial arguement to format.
[TODO: Explain XPG positional format specifiers.]
set g "OHIO" set fmtg [format "%-25.25s" $g] puts [string length "$fmtg"]The man page is complex enough that I want to be certain that I am not missing something. This seems to ensure that if g is longer than 25 characters, it is truncated, and if it is shorter than 25 characters, that it is left justified and blank padded. Are there any gotchas of which I need to be aware?
Note that format, by default, doesn't provide a way to use one of the number formats (like %d, etc.) AND specify a maximum number of digits. You could specify the format as a %s and then provide a maximum number of characters, or you could write tcl code to check for maximum. Jonathan Bromley posted, on comp.lang.tcl during early Sep 2007, this code, which provides a first cut at a "-strict" initial arguement to format.
proc strictformat {fmt value} {
set f [format $fmt $value]
regexp {%(\d+)} $fmt -> maxwidth
if {[string length $f]>$maxwidth} {
return [string repeat * $maxwidth]
} else {return $f}
}
rename format _format
proc format {args} {
if {[string equal [lindex $args 0] -strict]} {
eval strictformat $args
} else {
eval _format $args
}
}Tips and Tricks with format edit
Make Unsigned Values:
You can use [format] to produce unsigned integers for display (but don't reckon with them - for expr they're still signed!):% format %u -1 4294967295See floating-point formatting for discussion on how to write format strings to handle floats...DKF: Note that 8.5 makes this sort of thing much less necessary as we can now handle arbitrary width integers.
Nice Looking Floats:
To make numbers look nice:set fah [format "%0.2f" [expr $temperature_cel * 9 / 5 + 32]]
Color Formatting:
set color [format #%02x%02x%02x $r $g $b]
Converting Characters:
A limited formatting of decimals to characters is available in other languages, e.g. CHR() in Basic. If you use that more often, here's a cute shortcut: interp alias {} chr {} format %c
% set a [chr 49][chr 48]
10Abbreviating Integers:
See Narrow formatting for short rendering of big integers, with powers of 1024:% fixform 12345678 11.7M
Understanding Formats:
This method should get format string and explain the format structure. This is a fast scatch:proc explainFormat {formatStr vars} {
set index 1
foreach frm [split $formatStr "%"] {
set extra ""
set size 0
regexp {([0-9]+)([duioxXcsfegG])(.*)} $frm => size type extra
if {$size==0} {
set size [string length $frm]
} else {
set frm "%$size$type [lindex $vars 0]"
set vars [lrange $vars 1 end]
set size [string trimleft $size 0]
}
for {set i 0} {$i<2} {incr i} {
set newIndex [expr {$size +$index -1}]
puts "$index-$newIndex '$frm'"
set index [expr {$newIndex +1}]
if {$extra==""} {
break
} else {
set frm $extra
set size [string length $extra]
}
}
}
}
% explainFormat hello%02s000%3d $a $b
1-5 'hello'
6-7 '%02s $a'
8-10 '000'
11-13 '%3d $b'Emulating Fortran:
RS 2007-09-04: Here's emulating the FORTRAN behavior that numbers too large for the format are marked as an asterisk string: proc strictformat {fmt value} {
set f [format $fmt $value]
regexp {%(\d+)} $fmt -> maxwidth
if {[string length $f]>$maxwidth} {
return [string repeat * $maxwidth]
} else {return $f}
}Testing:% strictformat %5.2f 12.345 12.35 % strictformat %5.2f 123.45 ***** % strictformat %5.2f 12345.67 *****
Restricting Floats:
While using Tcl 8.5, you will begin to see strings like 0.0052499999999999995 where before you were seeing values like 0.00525. To round the value to a shorter value, try something like:format %.3g 0.0052499999999999995
Rebasing:
On comp.lang.tcl, Don Porter writes, in reply to a question about how to go from base 10 to another base, such as 2 or 16, using arbitrarily large numbers in Tcl 8.5:
> I would have guessed that "format %x" should do the job, but apparently
> it's currently limited to 64 bits...
% format %llx 1234567890123456789012345
1056e0f36a6443de2df79
(Note: Those are ELLs above in '%11x'. Not {percent eleven lower-case-x}, but rather {percent, ell, ell, lower-case-x}. DrASK)[TODO: Explain XPG positional format specifiers.]

