ActiveState Community

Tcl File handling

Posted by phi on 2009-03-26 11:40

Hi,

I'm trying to split a string and place the words in different variables. This is what i have so far, but im getting an error.

[code]
set source "Tom Holland 26"
regsub -all -- {[[:space:]]+} $source " " source
set source [split $source]
set counter "1"

foreach s_el $source
{
if {$counter == "1"}
{
set $Name $s_el
incr counter
}
elseif {$counter == "2"}
{
set $Country $s_el
incr counter
}
else
{
set $Age $s_el
}
}

label .line -text "Name : $Name"
label .Country -text "Country : $Country"
label .age -text "Age: $Age"
pack .line
pack .pass
pack .Country
[/code]

Here is the error im getting ::

[code]
wrong # args: should be "foreach varList list :varList list ...? command"
while executing
"foreach s_el $source"
(file "C:\TCLEXA~1\tclLoop.tcl" line 6)
[/code]

Please someone help,
Thanks.

jeffh | Thu, 2009-03-26 12:33

Your code is simply not in valid Tcl format. You cannot place the { on a line by itself. Please read the Tcl tutorial or other starter guide for more info.

phi | Fri, 2009-03-27 08:23

Ahh ok, i didn't know tcl is typed like this.

I'm still getting the error, here is what i changed the code to, in the if statement.

[code]
foreach s_el $source
if {$counter == "1"} {
set $Name $s_el
incr counter
}
elseif {$counter == "2"} {
set $Country $s_el
incr counter
}
else {
set $Age $s_el
}
[/code]

paul_danielson | Fri, 2009-03-27 09:10

You need to have braces enclosing the body of the foreach loop.
try this:

foreach s_el $source {
  if {$counter == "1"} {
    set $Name $s_el
    incr counter
  }
  elseif {$counter == "2"} {
    set $Country $s_el
    incr counter
  }
  else {
    set $Age $s_el
  }
}

If you are using version 8.5, you might take a look at the "lassign" command.

Regards,
Paul

phi | Tue, 2009-03-31 11:21

Hi,

lassign seems to be excately what im looking for. Can you please tell me how to make it work from a text file. I need to read the data from a text file, and store in variables.

Thanks so much.
Philip.

paul_danielson | Tue, 2009-03-31 12:42

Here's the general idea.
Regards,
Paul

# create a test file
set chan [open junk w]
puts $chan "Tom Holland 26"
puts $chan "Mot Dollanh 62"
close $chan

# load the test file
set chan [open junk r]
foreach line [split [string trim [read $chan]] \n] {
  lassign $line a b c
  puts "a=$a b=$b c=$c"
}
close $chan

phi | Wed, 2009-04-01 07:09

Paul,

Give me your address, i got some beer heading your way!!! :D

Thanks alot....

Philip.