. Note that this is not necessarily the same as the number of bytes used to store the string. If the object is a ByteArray object (such as those returned from reading a binary encoded channel), then this will return the actual byte length of the object.
Subcommand of
string, returns the length of its argument in (Unicode) characters, which may differ from the result of
string bytelength on the same string (because of the UTF-8 implementation).
If you want to use a name familiar from C, you might do this:
interp alias {} strlen {} string length
2003-10-17 in the
Tcl chatroom, some of us played around with silly pure-Tcl implementations of
string length:
proc strlen s {
set n 0
foreach char [split $s ""] {incr n}
set n
} ;# RS
proc strlen s {llength [split $s ""]} ;# AM
proc strlen string {
regsub -all . $string +1 string
expr 0$string
} ;# MS
jcw - does the above perhaps need a -all? Also, why not simply: return [regexp -all . $string]
MS indeed; corrected now. In the
why not simply department, why not
regexp -all . $string
or using aliases
interp alias {} strlen {} regexp -all . ;# MS
proc strlen string {expr 0[regsub -all . $string +1]} ;# dkf
The
functional way:
proc strlen {s} {
expr {[regexp {.(.*)} $s - s] ? (1+[strlen $s]) : 0}
} ;# EB
ulis, A
recursive way:
proc strlen {string} \
{
if {$string == ""} { return 0 } \
else { expr [strlen [string range $string 1 end]] + 1 }
}
And the classical
iterative way:
proc strlen {string} \
{
set n 0
while {$string != ""} { set string [string range $string 1 end]; incr n }
return $n
}
Powers of ten (sorrily, this works only for short strings):
proc strlen s {
expr round(log10(1.[regsub -all . $s *10]))
} ;# RS
At times, people ask which is better for determining whether a string is
empty (null):
[string equal x x$str]
[string equal "" $str]
![string compare "" $b]
[string length $str] == 0
![string length $str]
$str eq ""
The
string length or
string equal will be a bit quicker, as they will look to see if the strings are of equal size first.
Negative-length strings: A bug (SF 230589) in
regexp produces incredible consequences:
% regexp {[ ]*(^|[^@])@} "x@" m; puts [string length $m]
-109537
Numbers vary by platform, the above was 8.4.1 on Solaris. (
CMcC via
RS)