Précédent   Forum du club des développeurs et IT Pro > Autres langages > Perl > Langage
Langage Toutes vos questions sur les scripts Perl en général. Avant de poster, veuillez consulter les FAQs perl, les cours Perl, les critiques de livres et les sources Perl.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 30/11/2012, 12h51   #1
Glacealeau
Invité de passage
 
Inscription : novembre 2012
Messages : 7
Détails du profil
Informations forums :
Inscription : novembre 2012
Messages : 7
Points : 3
Points : 3
Par défaut Déclarer une table hash par itération

Bonjour,
Je souhaiterai déclarer une nouvelle table hash par tour de boucle.
Je pensais mettre un compteur de type :

$i=$i+1

Je voulais ensuite inclure ce compteur dans le nom de mon hash :

my %h$i

Je voudrai obtenir %h1, %h2... jusqu'à la fin de ma boucle.

Auriez vous une idée de la façon dont il faille l'écrire?
D'avance merci !
Glacealeau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/11/2012, 18h50   #2
Lolo78
Membre Expert
 
Homme Laurent R.
Conseil - Consultant en systèmes d'information
Inscription : mai 2012
Messages : 570
Détails du profil
Informations personnelles :
Nom : Homme Laurent R.
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Conseil - Consultant en systèmes d'information
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mai 2012
Messages : 570
Points : 1 121
Points : 1 121
Les références symboliques permettent de faire cela, mais leur utilisation est dépréciée avec les versions actuelles de Perl (et ce depuis au moins une douzaine d'années).

Il est préférable d'utiliser un hash de hashes (ou éventiellement un taleau de hashes, si tes valeurs sont toutes numérique), ave par exempole une syntaxe de e style:

Code :
$hash[$i]{'toto'} = "titi";
__________________
Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.
Lolo78 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 01/12/2012, 11h36   #3
Glacealeau
Invité de passage
 
Inscription : novembre 2012
Messages : 7
Détails du profil
Informations forums :
Inscription : novembre 2012
Messages : 7
Points : 3
Points : 3
Merci pour votre réponse !
J'ai donc essayé comme vous me l'avez conseillé, le tableau de hashes (car je n'ai que des valeurs numériques).

Cependant quand je lui demande d'imprimer ce tableau, j'obtiens :
HASH<0x48de10>HASH<0x4dbc10>HASH<0x4fe4f0> etc.

Je vais essayer d'en apprendre plus sur les tableaux/hashes de hashes.
Glacealeau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2012, 11h54   #4
Lolo78
Membre Expert
 
Homme Laurent R.
Conseil - Consultant en systèmes d'information
Inscription : mai 2012
Messages : 570
Détails du profil
Informations personnelles :
Nom : Homme Laurent R.
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Conseil - Consultant en systèmes d'information
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mai 2012
Messages : 570
Points : 1 121
Points : 1 121
Montre ton code, que l'on puisse t'aider à corriger ce qui ne va pas.

Mon exemple précédent était un peu inconsistant. Il aurait fallu écrire soit un hash de hashes::

Code :
$hash{$i}{'toto'} = "titi";
soit un tableau de hashes (en supposant $i toujours numérique):

Code :
$tableau[$i]{'toto'} = "titi";
sachant que je donne à mes variables les noms "hash" et "tableau" uniquement pour mieux clarifier leur nature dans l'exemple; dans ton vrai cas, utilise plutôt un nom spécifiant leur contenu.
__________________
Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.
Lolo78 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 01/12/2012, 12h34   #5
Glacealeau
Invité de passage
 
Inscription : novembre 2012
Messages : 7
Détails du profil
Informations forums :
Inscription : novembre 2012
Messages : 7
Points : 3
Points : 3
Voici mon code pour le moment :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
open fichier, ">>c:/data.txt";
my $rep = "C:/Donne";
$i=0;
my %f;
opendir(REP,$rep) or die "Dossier introuvable";
	while(defined(my $fic=readdir REP)){ 
	$i=$i+1;
	my $f="${rep}/$fic";
	open FIC, "$f" or warn "$f fichier introuvable";
		while (<FIC>){
		chomp($_);
		my @Tab=split("\t", $_);
		$a=@Tab[0];
		$b=@Tab[1];
		$h[$i]{$a} = $b;
		}
	}
Le but (dans un premier temps) est de contenir les valeurs de chaque fichier présent dans le répertoire, dans une hash.
Glacealeau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2012, 13h29   #6
Lolo78
Membre Expert
 
Homme Laurent R.
Conseil - Consultant en systèmes d'information
Inscription : mai 2012
Messages : 570
Détails du profil
Informations personnelles :
Nom : Homme Laurent R.
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Conseil - Consultant en systèmes d'information
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mai 2012
Messages : 570
Points : 1 121
Points : 1 121
Bonjour,

premier conseil: utilise toujours les pragmas suivants:

Code :
1
2
use strict;
use warnings;
Cela t'aider à détecter des erreurs qui tu risques de ne pas voir autrement. Par exemple, le tableau de hashes @h n'est pas déclaré (alors que tu déclares le hash %f que tu n'utilises pas).

Deuxième point, cette syntaxe n'est pas correcte:

Code :
1
2
		$a=@Tab[0];
		$b=@Tab[1];
Il faut écrire:

Code :
1
2
		$a=$Tab[0];
		$b=$Tab[1];
Mais il y a plus simple:

Code :
1
2
		my ($a, $b) = split("\t", $_);
		$h[$i]{$a} = $b;
Je réécrirais aussi les lignes 5 à 9 comme suit:

Code :
1
2
3
4
5
my @liste_fic = glob ("$rep/*.*");
foreach my $fichier(@liste_fic) {
     $i ++;
     open my $FIC, "<", "$fichier" or warn "impossible ouvrir $fichier $!";
     while (<$FIC>) { # ...
Pour l'impression, tu de donnes pas la ligne de code qui t'a donné une erreur, mais il suffit en principe d'une instruction comme celle-ci:

__________________
Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.
Lolo78 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 01/12/2012, 13h56   #7
Glacealeau
Invité de passage
 
Inscription : novembre 2012
Messages : 7
Détails du profil
Informations forums :
Inscription : novembre 2012
Messages : 7
Points : 3
Points : 3
Merci de l'aide, j'essaye ça demain et je te donne mes résultats !
Glacealeau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2012, 13h39   #8
Glacealeau
Invité de passage
 
Inscription : novembre 2012
Messages : 7
Détails du profil
Informations forums :
Inscription : novembre 2012
Messages : 7
Points : 3
Points : 3
Bonjour,
j'ai apporté les modifications que tu m'as recommandé, voici donc le code :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use strict;
use warnings;
open fichier, ">>c:/data.txt";
my $rep = "C:/Donne";
$i=0;
my %h;
my @liste_fic = glob ("$rep/*.*");
foreach my $fichier(@liste_fic) {
     $i ++;
     open my $FIC, "<", "$fichier" or warn "impossible ouvrir $fichier $!";
		while (<FIC>){
		chomp($_);
		my ($a,$b)=split("\t", $_);
		$h[$i]{$a} = $b;
		}
	}
print $h[1]{350};
En exécutant ce script, j'obtiens le message d'erreur suivant :

Global symbol "$i" requires explicit package name at c:\tr.pl line 5.
BEGIN not safe after errors--compilation aborted at c:\tr.pl line 7.
Glacealeau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2012, 23h53   #9
Lolo78
Membre Expert
 
Homme Laurent R.
Conseil - Consultant en systèmes d'information
Inscription : mai 2012
Messages : 570
Détails du profil
Informations personnelles :
Nom : Homme Laurent R.
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Conseil - Consultant en systèmes d'information
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mai 2012
Messages : 570
Points : 1 121
Points : 1 121
Ta variable $i n'est pas déclarée (ce qui est nécessaire avec le pragma 'use strict' que je t'ai conseillé. Change simplement la ligne 5 de ton code ci-dessus comme suit:

Tant que j'y suis, je vois au moins une seconde erreur entre les lignes 10 et 11:
- tu ouvres le descripteur de fichier $FIC en ligne 10
- tu utilises le descripteur de fichier FIC en ligne 11. Change la ligne 11 comme suit:

Tu auras sans doute un problème analogue avec %h, car h est un tableau de hashes (plus exactement un tableau de références vers des hash anonymes, mais, bon, ça veut dire la même chose), donc d'abord un tableau, et devrait donc être déclaré comme: "my @h;".

Le reste paraît correct à vue de nez, mais je te conseillerais d'utiliser des noms de variables plus parlants. Par exemple:

Code :
my ($a,$b)=split("\t", $_);
n'est pas très explicite. Ton code serait bien mieux auto-documenté si tu remplaçais $a et $b par des noms de variables décrivant le contenu de ces variables (comme je l'ai fait dans le code que j'ai proposé: "$fichier(@liste_fic)...", c'est bien plus clair que l'on examine chaque fichier d'une liste de fichiers). Idem pour "@h".
__________________
Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.
Lolo78 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 03/12/2012, 08h01   #10
Glacealeau
Invité de passage
 
Inscription : novembre 2012
Messages : 7
Détails du profil
Informations forums :
Inscription : novembre 2012
Messages : 7
Points : 3
Points : 3
Alors, déjà merci beaucoup pour ton aide, ça m'a permis de finir mon petit script, tout marche comme je le voulais !
Je vais changer les noms de mes variables histoires de m'y retrouver, comme tu me le conseil, et je pourrai passer à autre chose

Un grand merci !
Glacealeau est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 15h31.


 
 
 
 
Partenaires

Hébergement Web