Training, Open Source computer languages
PerlPHPPythonMySQLApache / TomcatTclRubyJavaC and C++LinuxCSS 
Search for:
Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
 
This week, we're updating our course layouts and descriptions. Presentation and materials always gently change over time, but just occasionally there's a need to make a step change to clear out some of the old and roll in the new. That's now happening - but over a long and complex site it's not instant and you'll see sections of the site changing up to and including 19th September.

See also [here] for status update
 
file handling in tcl

Posted by pkm117 (pkm117), 29 August 2005
I am an extremely new user of Tcl/Tk and want to do the following operation:

I have a file with several rows and space delimited columns of data. Each column is a particular variable. Thus, say 3 columns correspond to 3 variables and the rows correspond to repetitions of these variables. I want to read these variables from the file and input then into separate variables in my Tcl program. Also, i want to do this for each repetition of the same variables.  So, say I have 3 variables x, y, z in my Tcl program and i have 3 columns of data in my file, I want the first column to go into x, the second into y and the third into z. I want to be able to do this 20 times say (corresponding to the number of rows in the columns). If I can get the entire column for a particular variable into my x,y and z variables, thats fine too.

I have looked into several reference  guides but havent found a good answer. Any help would be greatly appreciated.

Thanks.

Posted by admin (Graham Ellis), 29 August 2005
Code:
set fh [open tcd.txt]

while {[gets $fh stuff] >= 0} {
  for {set k 0} {$k < [llength $stuff]} {incr k} {
      lappend result($k) [lindex $stuff $k]
       }
  }

foreach fname [array names result] {
       puts $result($fname)
  }


transforms

Code:
Alf 20 50
Ben 16 75
Claris 44 16
Den 50 20


into

Code:
Alf Ben Claris Den
20 16 44 50
50 75 16 20


You don't tell us what your delimiters are, so you may need to get involved with the split command ....

Posted by pkm117 (pkm117), 29 August 2005
Thanks for the reply Graham. My delimiter is a space. As you suggested in your example, the final output form that you provide using the code transformation is the form my data is already in. What i want to be able to do is take that data and read individual values from each column for each row into different variables and say "set variable A to the value in the first column and first row"; "set variable B to the value in the second column and first row" and so on, where A and B are some variables that I define and use later on the the Tcl code to do other stuff. It may just be that I am confused and this may be easy to do. Any help would again be greatly appreciated.

Thanks.

Posted by admin (Graham Ellis), 30 August 2005
I would suggest that at this stage you read up on lists and arrays.

In Tcl, a list is a string of text into which you can index so making it like an array in a conventional language in many ways. You simply set up the single string and then use commands like lindex to reference elements by number.

Lists have their individual elements delimited by a space character, and the first element is know and number 0 not number 1.   If you want to include a space within one of the elements, you can do so by using {} \ or " protection in the way the Tcl command line does.

Code:
% set people {Alf Ben {Claris May} Den}
Alf Ben {Claris May} Den
% lindex $people 0
Alf
% lindex $people 2
Claris May
% lindex $people 3
Den
%


An array is a variable that contains many strings, and you give the elements's key in round brackets after the name.  Since all variables contain strings in Tcl, the key is acually a string of text and that means that an array in Tcl acts rather like an associative array in PHP, or like a has in Perl or a dictionary in Python (if that comparision helps).

Technically, to answer your question I think you need an array of arrays as you ask for each element in its own variable.  However, a better and easier solution that you might not have considered is to save the incoming data as a list of lists and simply extract the item you wanted from the single long string each time using two nested calls to lindex.

Here's a further code example that implements that last suggestion.

Code:
set fh [open tcd.txt]

while {[gets $fh stuff] >= 0} {
    lappend datab $stuff
       }

set a [lindex [lindex $datab 1 ] 2]
set b [lindex [lindex $datab 1 ] 0]

puts $a
puts $b


Using the data I posted earlier in this thread, it gives

Code:
75
Ben




This page is a thread posted to the opentalk forum at www.opentalk.org.uk and archived here for reference. To jump to the archive index please follow this link.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2014: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 899360 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho