Skip to content
VLSI Mentor

Tcl Part I · Module 5 · Strings

string length, and What a Character Is

Measuring a string is the simplest thing in this module, and it takes one line. The chapter exists for the question underneath it: what exactly is being counted? Tcl counts characters, not bytes, and for plain English text those are the same number so the distinction never surfaces. The moment an accented letter or any non-English text arrives they stop being the same, and knowing which one you have is the difference between a correct column width and a misaligned report.

Foundation9 min readTclPart IStringsLengthEncoding

Part I · Module 5 · Chapter 5.2 · string length, and What a Character Is

1. The Command

Azvya Education Pvt. Ltd.VLSI Mentor
basic.tcl
puts [string length "summary"]
puts [string length ""]
puts [string length "a b c"]
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
7
0
5

Seven characters, zero, and five — the spaces count, because they are characters in the string.

The empty string is 0, which is worth seeing because it is the basis of the most common use of this command.

2. The Most Common Use: Is It Empty?

Azvya Education Pvt. Ltd.VLSI Mentor
empty-check.tcl
set name ""

if {[string length $name] == 0} {
    puts "no name supplied"
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
no name supplied

That works, and there is a shorter way that reads better:

Azvya Education Pvt. Ltd.VLSI Mentor
empty-better.tcl
set name ""

if {$name eq ""} {
    puts "no name supplied"
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
no name supplied

Both are correct. eq says "is it the empty string" directly, which is what you meant — Chapter 4.4. Use string length when you need the number for something else, not merely to compare it with zero.

3. Characters, Not Bytes

Now the part worth the chapter:

Azvya Education Pvt. Ltd.VLSI Mentor
characters.tcl
set word "café"

puts "characters: [string length $word]"
puts "bytes as UTF-8: [string length [encoding convertto utf-8 $word]]"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
characters: 4
bytes as UTF-8: 5

Four characters — c, a, f, é. Five bytes, because é needs two of them in UTF-8.

Tcl counts characters. For "summary" the two numbers are identical, which is why the distinction stays invisible in most scripts. It becomes visible the first time a name, a comment, or a field contains anything outside plain ASCII.

4. Which One Do You Want?

Almost always characters, which is what you already get:

  • Lining up a column — characters. A report column is a count of visible positions.
  • Truncating a name to fit — characters. Cutting mid-character would corrupt the text.
  • Validating a maximum length — usually characters, unless a specification says bytes.
  • Sizing a file or a buffer — bytes. This is the exception.

For the exception, convert and then measure, as §3 did:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
string length [encoding convertto utf-8 $text]

5. Length of Things That Are Not Obviously Strings

Every Tcl value has a string representation — Chapter 3.1 — so string length works on anything:

Azvya Education Pvt. Ltd.VLSI Mentor
anything.tcl
puts "number:  [string length 12345]"
puts "real:    [string length 3.14]"
puts "list:    [string length {a b c}]"
puts "result:  [string length [expr {2 ** 20}]]"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
number:  5
real:    4
list:    5
result:  7

The list case is the one to notice. {a b c} as text is five characters — a, space, b, space, c. If you wanted the number of elements you want llength, which is Module 6:

Azvya Education Pvt. Ltd.VLSI Mentor
llength.tcl
set items {a b c}

puts "string length: [string length $items]"
puts "llength:       [llength $items]"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
string length: 5
llength:       3

Two different questions about the same value, which is Chapter 3.1 §4 exactly.

6. A Practical Use: Padding a Column

Azvya Education Pvt. Ltd.VLSI Mentor
padding.tcl
set names {clk reset data_valid rx}

foreach n $names {
    set pad [string repeat "." [expr {14 - [string length $n]}]]
    puts "$n$pad ok"
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
clk........... ok
reset......... ok
data_valid.... ok
rx............ ok

The padding is computed from the length, so the column lines up regardless of the name.

That said, format does this directly and handles the arithmetic for you — Chapter 5.11:

Azvya Education Pvt. Ltd.VLSI Mentor
padding-format.tcl
foreach n {clk reset data_valid rx} {
    puts [format "%-14s ok" $n]
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
clk            ok
reset          ok
data_valid     ok
rx             ok

Use format for alignment. Use string length when you need the number itself.

7. Common Mistakes

Comparing the length with zero to test for empty. $s eq "" says it better. §2.

Calling it on an unset variable. That is an error, not 0. §2.

Using it to count list elements. That is llength. §5.

Assuming characters equal bytes. True for ASCII only. §3.

Using bytelength for on-disk size. §4.

Computing padding by hand when format would do it. §6.

8. Exercises

Exercise 1 — three lengths. Measure "hello", "", and "a b" (two spaces). Predict each first.

Exercise 2 — characters versus bytes. Measure a word containing an accented letter both ways, as in §3. Then try a word with two accented letters and predict the byte count before running it.

Exercise 3 — two questions. For the value {red green blue}, produce both the character count and the element count. Say in one sentence why they differ.

Exercise 4 — the empty test, three ways. Test whether a variable is empty using string length, using eq, and using string equal. Which would you keep, and why?

Exercise 5 — build a ruler. Print a line of 50 dashes using string repeat, then a line that is exactly as long as a name you choose. Use string length for the second.

Exercise 6 — align without format. Line up three names in a 12-character column using only string length and string repeat. Then do it again with format and compare the two versions.

9. Remember

  • string length $text counts characters. The empty string is 0.
  • To test for empty, prefer $s eq "" — it says what you mean.
  • On an unset variable it is an error, not 0.
  • Characters are not bytes once text leaves ASCII. "café" is 4 characters and 5 bytes.
  • Count characters unless you are sizing storage, and convert with encoding convertto utf-8 when you are.
  • string bytelength is not the on-disk size.
  • It works on any value, because every value has a string representation — but llength is what counts list elements.
  • For alignment, format is the better tool.

Next: getting at individual characters and spans.

Where this fits

Part of the Tcl curriculum.