next up previous contents index
Next: Programmation avec Tk Up: Programmation en Tcl/Tk Previous: Programmation en Tcl/Tk

   
Programmation avec Tcl

Un exemple simple pourrait être un script qui compte les lignes d'un fichier, et affiche le résultat à l'écran. Cet exemple utilise des commandes très souvent utilisées : lecture des arguments, ouverture et lecture d'un fichier, calculs, affichage du résultat à l'écran...Cet exemple tient en très peu de lignes et montre la puissance d'un script shell.

 

#!/usr/bin/tclsh


# Fichier lc.tcl.
# Un exemple tres simple d'utilisation de Tcl.

# Essayer "lc.tcl lc.tcl"...


if {$argc != 1} {
error "lc <fichier>"
}

set lefichier [open [lindex $argv 0] r]
set compte 0

while {[gets $lefichier ligne] >= 0} {
    set compte [expr $compte + 1]
}

puts "Lu $compte lignes."

Allez, on passe au gros morceau...

#!/usr/bin/tclsh


# Fichier simple.tcl.
# Exemple de programmation en Tcl.


puts ""
puts "Salut a \
tout le monde !"

set long [string  length "Salut a \
           tout le monde !"]
puts "$long characteres dans la phrase precedente..."

puts "Il y a [string length bonjour] caracteres dans 'bonjour'"

# Les {} forment un seul argument...

puts {Il y a [string length bonjour] caracteres dans 'bonjour'}
puts ""


# else doit se trouver sur la meme ligne que l'accolade fermant le if.
# L'espace entre if/else et '{' est primordial !

set pi 3.1416
if {$pi==3.1416} {puts "pi=$pi"} else {puts "pi <> 3.1416"}


# L'exemple qui suit montre elseif et comment lire une entree.

puts ""
puts "entrer un chiffre 0<chiffre<10 :"
set chiffre [gets stdin]
if {$chiffre >=7} {
    puts "chiffre >=7"
} elseif {$chiffre >=4 && $chiffre < 7} {
    puts "4<=chiffre<7"
} elseif {$chiffre >=2 && $chiffre<4} {
    puts "2<=chiffre<4"
} else {
puts "chiffre <1 ou chiffre >10"
}
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin


# Exemple d'utilisation de la boucle while :
# 1=vrai et utilisation de 'continue' et 'exit'.

set i 0
set somme 0

while {1} {
    incr i ;# i++
    if {$i==5} {continue}; # sauter si i=5
    if {$i>10} {break}; # fin de la boucle i
    set somme [expr $somme+$i];

puts $i
}

puts "Somme=$somme"
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin

for {set i 0; set somme 0} {$i<=10} {incr i} {
    set somme [expr $somme+$i]
puts $i
}
puts "Somme $somme"
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin


# Exemple d'utilisation de la commande 'foreach'.

set somme 0


# La variable 'i' n'a pas besoin d'etre initialisee...

foreach i { 1 2 8 9 10 } {
    set somme [expr $somme+$i]
puts $i
}
puts "Somme $somme"
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin


# Autre exemple pour lire les mots d'une phrase.

set mathieu "root c'est sympa"
foreach mot $mathieu {
puts "$mot"
}
puts ""


# Exemple d'affichage d'un prompt.

set prompt "Entrer la commande (\"help\" ou \"quit\" pour sortir) :"

puts "$prompt"

# On peut aussi mettre :
#    puts -nonewline "$prompt"
# pour que les entrees clavier soient affichees sur la meme ligne...


while { [gets stdin commande] != -1} {
    switch -exact -- $commande {
        help {puts "help quit start draw"}
        quit {puts "Au revoir !"; break}
        start {puts "Demarrage"}
        draw {puts "Dessine"}
        default {puts "Commande inconnue : $commande"}
}
puts "$prompt"
}
puts ""


# Pour comparer avec une expression rationnelle, utiliser '-regexp'

puts "*******************************************"
puts " Entrer une ligne commencant par q, s ou d "
puts "*******************************************"
puts ""

puts "$prompt"

while { [gets stdin commande] != -1} {
    switch -regexp -- $commande {
        ^q.* {puts "Bye !"; break}
        ^s.* {puts "commance par \"s\""}
        ^d.* {puts "commance par \"d\""}
        default {puts "Commande inconnue : $commande"}
}
puts "$prompt"
}
puts ""


# Exemple d'utilisation d'une fonction.
# Definition de la fonction.

proc total elements {
set somme 0
    foreach i $elements {
        set somme [expr $somme+$i]
    }
return $somme
}

# Utilisation de la fonction avec 1 argument.

set comptes "5 4 3 5"
puts "Total=[total $comptes]"

# Utilisation de la fonction avec plusieurs arguments.

set somme1_10 [total {1 2 3 4 5 6 7 8 9 10}]
puts "et de 1->10 : $somme1_10"

# Le nom de l'argument de la fonction a peu d'importance...

proc total args {
set somme 0
    foreach i $args {
        set somme [expr $somme+$i]
    }
return $somme
}

set somme1_10 [total 1 2 3 4 5 6 7 8 9 10]
puts "et de 1->10 bis : $somme1_10"
puts ""


# Utilisation de la commande string.

puts "devinez mon prenom..."
gets stdin commande
if {[string compare $commande "mathieu"]==0} {
puts "gagne !"
} else {
puts "perdu !"
}
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin


# Utilisation de tablaux.
# Le tableau partition contient le nom des partitions.
# Le tableau disque_utilise contient la taille de la partition.

set partition(1) "/Dos"
set partition(4) "/"
set partition(5) "/home"
set partition(6) "/usr"

set disque_utilise($partition(1)) 701
set disque_utilise($partition(4)) 94
set disque_utilise($partition(5)) 48
set disque_utilise($partition(6)) 756

foreach n {1 4 5 6} {
puts "Disque utilise par $partition($n) = $disque_utilise($partition($n))M"
}


# On peut aussi utiliser des variables d'environnement...

puts "la variable PATH a pour valeur $env(PATH)"
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin


# Exemple d'ecriture dans un fichier.

set fichier [open "fictest" w]
puts $fichier "hello !"
close $fichier


# Les deux formes suivantes sont equivalentes :
#     set line [gets stdin]
#     gets stdin line


# Il y a 3 facons de lire un fichier :

puts "Il y a 3 facons de lire un fichier :"
puts ""

puts "Facon 1 : ligne par ligne."
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin
puts "----------------------------------------------------------"

set pass [open "/etc/passwd" r]
while { [gets $pass line] != -1} {
puts $line
}
close $pass

puts ""
puts "Facon 2 : par packets de 20 octets."
puts "----------------------------------------------------------"
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin

# Par packets de 20 octets.

set f1 [open "/etc/passwd" r]
while {![eof $f1]} {
    set buffer [read $f1 20]
puts $buffer
}
close $f1

# Par caractere ("\n", fin de ligne ici).

puts ""
puts "Facon 3 : par caractere (\"\\n\", fin de ligne ici)."
puts "----------------------------------------------------------"
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin

set f3 [open "/etc/passwd" r]
set buffer [read $f1]
split $buffer "\n"

foreach Axelle $buffer {
puts $Axelle
}
close $f3
puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin


# Pour tous les fichiers se terminant par '.tcl'.

puts "Fichiers scripts Tcl :"
foreach fichier [glob *.tcl] {
puts $fichier

# On peut ensuite ouvrir chaque fichier en lecture par ex et le traiter...
}

puts ""

set outfile [open simple.out w];


# Execution d'une commande UNIX.
# On peut rediriger la sortie ou l'entree, utiliser des pipes...

exec ls

# Equivalant de "ls *.tcl".

eval exec ls [glob *.tcl];


puts ""
puts "Appuyer sur une touche pour continuer..."
puts ""
gets stdin


# Exemple de traitement des lignes d'un fichier.

set fid [open "/etc/passwd" r];

# Recuperation des informations ligne par ligne.
# Decoupage de chaque ligne en champs separes par ":".
# Extrait du premier champ (indice 0).

while {[gets $fid line] != -1} {
    set fields [split $line ":"];
    puts [lindex $fields 0];
}


# join rassemble plusieurs elements en un seul, en precisant le
# separateur de champ.
# Ici, les elements sont separes par un espace.

puts ""
set x {1 2 3 4 5 6}
set y [join $x ""]
puts $y



MATHIEU DECORE
1999-11-03
Merci de me dire ce que pensez de ce document.