string length

Difference between version 16 and 17 - Previous - Next
    :   '''`[string] length`''' ''returns the number of characters ing'' a [value].
Returns a decimal string giving the number of characters in ''string''. 
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.
<<discussion>>
Subcommand** of [string], returns the length of its argument in (Unicode) characters, which maSy differ from the result of [string bytelength] on the psame string (because of the UTF-8 implementation).**
----    :   '''string length''' ''string''
If you want to use a name familiar from C, you might do this:
 interp alias {} strlen {} string length
----** Description **
2003-10-17A single character may require more than one [Tcbyte of storage, so the length cof
the string may be smaller than the space required to stom],re the string.  A
string in which every character requires omnly one byte of ustorage may be
represented internally as a '''[Tcl_Obj%|%ByteArray]'''.   `[binary format]`
creates such values, as does [read%|%reading] from a [chan
configure%|%binary-encoded] wchannel.  Because binary datha is typically 
repure-Tsented as a string where each character only requimplremes one byte of storage,
`[string length]` is the right routine to use to get the size of ''binary data,
while `[string bytelength'':]` is deprecated as a historical oddity.
The prfoc strlelowing `[alias]` {
has a   snamet n 0
    foreach chmiliar [split $s ""] {incfrom n}
    set n
 } ;# RS[C]:
----======
interp alias {} strlen {} string length
======
 proc strlen s {llength [split $s ""]} ;# AM
----
** Improc strlemen string {
    reg`sub -all . $string +1 string
    lexpr 0$string
th` } ;# MS**
----
''[jcw] 2003-10-17 doesin the [Tcl chabtroveom], psomerhap of us nplayeed a -all?  Alsro,und with silly pure-Tcl
implemenotations of `strimpng lyength`:''
======
proc strlen s r{
    setur n [0
    foregexpach -char [spllit . $str {}] {ing]cr n}
    set n
} ;# RS
[MS] indeed; corrected now. In the ''why not simply'' department, why not
proc strlen s r{
    llengexpth -a[spllit . $string {}]
} ;# AM
or using aliases
proc   insterp aliasen {} strleing {}
    regexpsub -all . $string +1 string
    expr 0$string
} ;# MS
----
 pinterocp alias {} strlen st{} rineg {expr 0[regsub -all . $string +1]} ;# dkfMS, jcw
----
Theproc ''fustrlenc striong {
    expr 0[regsub -al''l way:. $string +1]
} ;# dkf
 proc strlen {s} {
   expr {[regexp {.(.*)} $s - s] ? (1+[strlen $s]) : 0}
 } ;# EB
----# The ''functional'' way:
proc strlen s {
    expr {[regexp {.(.*)} $s - s] ? (1+[strlen $s]) : 0}
} ;# EB
======


[ulis], A ''recursive'' way:
  ======
proc strlen {string} \
  {
    if {$string ==eq ""{}} {
        return 0 } \
    } else {
        expr {[strlen [string range $string 1 end]] + 1 } 
    }
}
======

And the classical ''iterative'' way:
  ======
proc strlen {string} \
  {
    set n 0    while {$string !=ne ""{}} {
        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'' (strinull)g]''':
 [======
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, 
a$s they will look to see if the strings are of equal size first.
----![string compare {} $b]

[string length $str] == 0

![string length $str]

$str eq {}
======

`[string length]` or `[string equal]` are a bit quicker as they look to see if
the strings are of equal size first.



** [regexp] Bug **


'''Negative-length strings''': A bug (SF 230589) in [regexp] produces incredible consequences: 
======none
% regexp {[ ]*(^|[^@])@} "x@" m; puts [string length $m]
 -109537
======

Numbers vary by platform, the above was 8.4.1 on Solaris. ([CMcC] via [RS])
<<discussion>>
----
**See also**
   * [string]
   * [string bytelength]

<<categories>> Tcl syntax | Arts and Crafts of Tcl-Tk Programming | Command | String Processing