[Perl] Passage de tableau à une fonction

Résolu/Fermé
frangipane44 Messages postés 70 Date d'inscription vendredi 3 décembre 2004 Statut Membre Dernière intervention 11 octobre 2012 - Modifié par frangipane44 le 30/08/2010 à 19:04
frangipane44 Messages postés 70 Date d'inscription vendredi 3 décembre 2004 Statut Membre Dernière intervention 11 octobre 2012 - 31 août 2010 à 09:47
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.


A voir également:

2 réponses

lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
Modifié par lami20j le 31/08/2010 à 09:46
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
frangipane44 Messages postés 70 Date d'inscription vendredi 3 décembre 2004 Statut Membre Dernière intervention 11 octobre 2012 2
31 août 2010 à 09:47
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!
0