2

I'm having troubles getting some parts out of a string.

Here is my code :

  set top [layout peek $::openedFiles($key) -topcell]
  set dim [layout peek $::openedFiles($key) -bbox $top] 
 # yields output "{name{x1 y1 x2 y2}}"

  set coord [split $dim " "]
  set x1 [lindex $coord 0]
  set x2 [lindex $coord 2]
  set y1 [lindex $coord 1]
  set y2 [lindex $coord 3]

When I call the command set dim [layout peek $::openedFiles($key) -bbox $top], I get the dimensions back from the loaded file. These dimension are coordinates. The output is always like this: "{name {x1 y1 x2 y2}}".

For example : {test {0 0 100 100}}

I want to get the four coordinates out of the string so I can place them in an array. I tried splitting the string based on a space, but without success. (keep getting this error: can't read "coord\{clock \{0 0 99960 99960\}\}": no such variable)

Anybody got some thougths?

Jerry
  • 70,495
  • 13
  • 100
  • 144
Jerre_111
  • 79
  • 1
  • 9
  • Is the response _really_ `{test{0 0 100 100}}` ? I'd expect it to be more like `{test {0 0 100 100}}`, that is, a two-element list, where the second element is, itself, a four element list. – nurdglaw May 28 '13 at 08:20
  • @ nurdglaw Yes I'm sorry, the respons is like this `{test {0 0 100 100}}` indeed – Jerre_111 May 28 '13 at 08:27
  • Don't worry about it, but a lot of programming, and even more debugging, consists of spotting just that kind of detail :-) – nurdglaw May 28 '13 at 08:32

2 Answers2

4

If you are using a sufficiently recent Tcl, or an older Tcl with the appropriate package - sorry I can't remember details; let me know if you want me to go and dig them out - then you can do

set dim [layout peek $::openedFiles($key) -bbox $top]
lassign $dim firstBit coords
lassign $coords x1 x2 y1 y2

with an older version, and without the extension,

set dim [layout peek $::openedFiles($key) -bbox $top]
set coords [lindex $dim 1]
set x1 [lindex $coords 0]

# etc.

Edit

It turns out that [layout peek...] works slightly differently, so the final working code was

set dim [layout peek $::openedFiles($key) -bbok $top]
set temp [lindex $dim 0]
set coords [lindex $temp 1]
set x1 [lindex $coords 0]
set x2 [lindex $coords 1]
set y1 [lindex $coords 2]
set y2 [lindex $coords 3]

The OP is using Tcl8.4, without TclX.

There's probably scope for improving the variable names, but...

nurdglaw
  • 2,107
  • 19
  • 37
  • In the interests of completeness; if you are using Tcl 8.5 or later, then `lassign` is available to you, for earlier versions, you'd need the TclX package. – nurdglaw May 28 '13 at 08:34
  • Thanks for your answer. I'm using tcl 8.4. So he doesn't recognize the lassign command... However using your second answer also doesn't seem to work. When I use `puts x1` the output is empty code :`set coords [lindex $dim 1] set x1 [lindex $coords 0] set y1 [lindex $coords 1] set x2 [lindex $coords 2] set y2 [lindex $coords 3] puts $x1 puts $y1 puts $x2 puts $y2` Am I doing something wrong? – Jerre_111 May 28 '13 at 08:42
  • Have you looked at the value of `dim` on the same run? The value of `coords`? My favourite typo leading to this kind of problem is to leave out a dollar sign, perhaps you've got `set coords [lindex dim 1]` which would make coords empty as well as x1. – nurdglaw May 28 '13 at 08:45
  • I've tried to put `dim` and `coords`. `Dim` is correctly, however `coords` is empty for some reason.. my code is this `set coords [lindex $dim 1]` copied it directly from my script.. – Jerre_111 May 28 '13 at 08:48
  • What's the value of `dim` when `[lindex $dim 1]` returns empty? – nurdglaw May 28 '13 at 08:53
  • the value of `dim` is this: `{design {0 0 99960 99960}} ` these are the actuall values of `dim`. But when I use `set coords [lindex $dim 0]` the value of `coords` is the following: `design {0 0 99960 99960}` – Jerre_111 May 28 '13 at 08:57
  • 1
    Ah! Very mysterious. It seems that [layout peek...] is returning a one-element list, where the first element is a two element list, whose second element is the four-element list of coordinates that you're after. In this case, try `set temp [lindex $dim 0]` followed by `set coords [lindex $temp 1]`. (Incidentally, are you really doing `set coords [lindex $dim 0]`? It ought to be `... 1]` - details, details :-) ) – nurdglaw May 28 '13 at 09:02
  • YES, that did the trick! it would have took ages before I would find out that the layout peek returns a on-element list. THANKS! – Jerre_111 May 28 '13 at 09:05
0

You can use the regular expression to extract all the number out of that string, then assign as usual:

# Assume dim = "{test {0 0 100 100}}"
set coord [regexp -inline -all {\d+} $dim]; # coord is now a list: "0 0 100 100"
set x1 [lindex $coord 0]
# set x2, y1, y2, ...
Hai Vu
  • 37,849
  • 11
  • 66
  • 93