[Perl] Passage de tableau à une fonction [Résolu/Fermé]

Signaler
Messages postés
70
Date d'inscription
vendredi 3 décembre 2004
Statut
Membre
Dernière intervention
11 octobre 2012
-
Messages postés
70
Date d'inscription
vendredi 3 décembre 2004
Statut
Membre
Dernière intervention
11 octobre 2012
-
Bonjour,

je début en perl et j'essaye un truc tout bête : vérifier qu'une chaîne de caractères existe dans un tableau de chaîne de caractères.

#!/usr/bin/perl  

my @gens = ("Pierre", "Alfred", "Marcel");  
if (in_array( "Alfred", \@gens)){  
  print "trouve";  
}  
else {print "pas dans le tableau";}  



 sub in_array()  
 {  
   my $val = shift;  
   my $tab = shift;  
   my $taille = scalar(@tab);  
     
  $i = 0;  
  $trouve=0;  
  while (($i < $taille) && (!($trouve))) {       
       if ($tab[$i] eq $val) {  
              $trouve=1;  
        }        
       $i++;  
  }
  return $trouve;  
 }  

Après exécution, j'ai le résultat "pas dans le tableau"

Cela ne fonctionne donc pas mais je ne vois pas pourquoi. Mon tableau transmis dans ma fonction est vide, la taille de mon tableau dans la fonction est de 0 alors qu'avant de passer dans la fonction elle est bien de 3. Bref si quelqu'un voit mon erreur, je l'en remercie grandement car je ne vois pas du tout.

Merci d'avance.


2 réponses

Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 542
Salut,

Toujours utiliser au début de script use strict;use warnings;
Ca te permettra de voir les erreurs et/ou warnings.

J'ai mis en gras les modifications.
Tu as utilisé my et ensutie dans la boucle tu n'as plus eu envie pour $i et $trouve.
Il faut être cohérent dans la syntaxe et une fois que tu as opté pour une façon de le faire alors il faut la respecter rigureusement. Pas de pitié, Perl te laisse tout faire, alors il faut apprendre bien gérer.

Tu utilises dans ton appel de fonction une référence pour le tableau.
C'est bien, comme ça les arguments ne sont pas mis à plat dans une liste.
En revanche dans la fonction tu ne géres pas bien la référence.

$val après le 1er shift contient le terme à chercher "Alfred"
$tab après le 2ème shift contient un scalaire qui est une référence vers un tableau
Jusqu'ici c'est OK

Ensuite tu commences les boulettes ;-)

$taille=scalar(@tab) c'est une erreur. Le tableau @tab n'existe pas.
Ce qu'on a c'est $tab qui est une référence. C'est comme $tab sera le nom de tableau si tu veux (ça pour faire simple)
Donc on écrit le sigil @ suivi de nom de tableau, ce qui donne @nom_de_tableau.
Dans ton cas le nom de tableau et $tab donc ça donne @$tab. Voilà, c'est ça ton tableau.

On continue le raisonnement et dans la boucle on écrit ${$tab}[i] et pas $tab[i]
Pourquoi?
Pour accèder à un élément d'un tableau on utilise le sigil $ suivi de nom de tableau et entre les crochets l'indice.
Ca donne en général $nom_tableau[indice]
Dans ton cas on a le nom de tableau $tab donc ça donne ${$tab}[i]
Je mets les accolades pour bien définir le nom de tableau et pour eviter les éventuelles erreur.

Vu que l'appel de la fonction se fait avant la définition de la fonction on l'appelle en utilisant l'esperluette

Voici le warning que j'ai si je ne mets pas l'esperluette

main::in_array() called too early to check prototype at in_array.pl line 5.
trouvé


#!/usr/bin/perl       
use strict;use warnings;       
my @gens = ("Pierre", "Alfred", "Marcel");       

if (&in_array( "Alfred", \@gens)){       
  print "trouvé\n";       
}else {       
  print "pas dans le tableau";       
}       


 sub in_array()       
 {       
   my $val = shift;       
   my $tab = shift;       
   my $taille = scalar(@$tab);       

  my $i = 0;       
  my $trouve=0;       
  while (($i < $taille) && (!($trouve))) {       
       if (${$tab}[$i] eq $val) {       
              $trouve=1;       
        }       
       $i++;       
  }       
  return $trouve;       
 }


Si le but est juste de voir comment on utilise les fonctions, je suis d'accord.
Toutefois il faut essayer de programmer en Perl et pas en C ;-))

Voici d'autres versions de ton programme

#!/usr/bin/perl     
use strict;use warnings;     
my @gens = ("Pierre", "Alfred", "Marcel");     

if (grep {/\bAlfred\b/} @gens){     
  print "trouve";     
}else {     
  print "pas dans le tableau";     
}


Et si tu veux avec une fonction personnalisée

#!/usr/bin/perl     
use strict;use warnings;     
my @gens = ("Pierre", "Alfred", "Marcel");     

if(&cherche("Alfred")){     
  print "trouvé\n";     
}else{     
  print "pas trouvé\n";     
}     

sub cherche(){     
  my $val=shift;     
  my @res=grep {/$val/} @gens;     
  return scalar @res;     
}


Ou encore
#!/usr/bin/perl    
use strict;use warnings;    
my @gens = ("Pierre", "Alfred", "Marcel");    

if(&cherche("Alfred")){    
  print "trouvé\n";    
}else{    
  print "pas trouvé\n";    
}    

sub cherche(){    
  my $val=shift;    
  return grep {/$val/} @gens;    
}


Ou avec le test sur une seule ligne

#!/usr/bin/perl   
use strict;use warnings;   
my @gens = ("Pierre", "Alfred", "Marcel");   

(grep {/Alfred/} @gens)?print "trouve":print "pas dans le tableau";   

GNU/Linux:Linux is Not Ubuntu! Quel linux choisir ne veut pas dire votre Distribution préférée,
106485010510997108
5
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Messages postés
70
Date d'inscription
vendredi 3 décembre 2004
Statut
Membre
Dernière intervention
11 octobre 2012
2
Bon bah que dire...? Extra! J'ai appris plein de trucs. Tout ça devrait bien me servir.

En ce qui concerne le grep, j'avais cru lire sur un autre forum que ça n'était pas recommandé pour la recherche dans un tableau. Comme un idiot j'avais pas vérifié...

Je reviendrais peut-être bientôt quand je devrais manipuler les matrices...

Merci!