Jeu du pendu - Problème d'accents

Ce sujet est résolu
Default
,

Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

Je suis en stage et je suis face à un code d'un jeu du pendu créé par d'anciens stagiaires qui n'ont pas réussi à afficher les accents.
Je cherche un mot dans la base de données, mets les lettres en majuscule, affiche sa première et dernière lettre et transforme les underscores par rapport à la longueur du mot.
Cela se visualise à peu près comme ça avec par exemple le mot "encore" : E _ _ _ _ E

        if(!isset($_SESSION['mot'])) 

    {
        $mot = GestionPendu::getMot($_COOKIE['niveau']);

        $mot_exist = 0;

        foreach($_SESSION['mots_gagnants'] as $motgagn){

            if($motgagn == $mot and $mot_exist != 1){

                $mot = GestionPendu::getMot($_COOKIE['niveau']);

                $mot_exist = 1;
            }
        }

                $mot = mb_strtoupper($mot);  
                $longueur = mb_strlen($mot);
                $mask = str_repeat('_',$longueur-2);  // on masque et on enleve 2 caractères représentant la première et la dernière lettre
                $reponse = mb_substr($mot,0,1).$mask.mb_substr($mot, $longueur-1 ,1); // on concatène la 1ère lettre , les caractères masqués et la dernière lettre 

        $_SESSION['mot']= $mot; 

        $_SESSION['longueur']= $longueur;

        $_SESSION['liste']=""; 

        $_SESSION['reponse'] = $reponse; //Concaténation des éléments de réponse précendents

        $_SESSION['coups_restants']= 10;

    }

    elseif(isset($_POST['lettre']))

    {

        $lettre= mb_strtoupper($_POST['lettre']);

        if(Recherche_Chaine_Dans_Tableau($_SESSION['liste'],$lettre)===FALSE)
        {

            if(Actualise_Reponse($lettre)==0) $_SESSION['coups_restants']--;

        }
    }

Ce que je veux

Tous les accents sont visibles, que ce soit dans le texte de la page, sur les lettres que l'on clique pour trouver le mot. Ce qu'il me manque et ce que je veux c'est corriger l'affichage des accents sur le mot cherché dans la base de données. Il faut que cela affiche "É _ _ _ E" contrairement à ce que j'obtiens.

Ce que j'obtiens

Lorsque je veux afficher un mot comme "élève" cela affiche : ? _ _ _ _ _ E.
La lettre avec accent est remplacé par un point d'interrogation et ajoute un caractère en plus.
Si je sélectionne d'ailleurs la lettre È le mot affichera "? _ _ ? _ _ E".
Ce que j'ai remarqué c'est que lorsque je fais un "echo $Mot", ÉLÈVE s'affiche parfaitement. C'est lors de l'affichage spécifique de la lettre que cela pose problème, "echo $mot[0]" et "echo $mot[1]" affichent un "?" avec l'exemple du mot "élève".

Je vous remercie d'avance pour tout aide que vous pourriez me solliciter et je reste présent pour tout autre question si jamais cela manque de précision.

9 Réponse

Default
,

Bonsoir,
C'est la plaie ces caractères multi-octet :D
Si tu ne veux pas trop modifier le code , tu peux "feinter" en passant par les fonctions utf8_decode() et utf8_encode()...
Par exemple :
tu remplaces : $reponse = mb_substr($mot,0,1).$mask.mb_substr($mot, $longueur-1 ,1); par :

$reponse =utf8_decode(mb_substr($mot,0,1).$mask.mb_substr($mot, $longueur-1 ,1));

dans ta fonction Actualise_Reponse() tu remplaces

$i=strpos($_SESSION['mot'], $lettre, $i+1);
if($i>0 && $i<($_SESSION['longueur'])-1)
{
$_SESSION['reponse'][$i]=$lettre ;
$NbLettre++ ;
}
par :

    $i=mb_strpos($_SESSION['mot'], $lettre);
    if($i>0 && $i<($_SESSION['longueur'])-1)
    { 
      $_SESSION['reponse'][$i]=utf8_decode($lettre) ;
      $NbLettre++ ;
    }

Quand tu affiches ta réponse tu fais alors un :
utf8_encode($reponse);

Default
,

Bonsoir ,
J'ai l'impression que c'est le même problème qu'avec ucfirst pour les caractères accentués . ( ca vient de la place que prend un caractère accentué qui est plus important que le même caractère non accentué ...si je me souviens bien)
Perso , pour strtoupper ou ucfirst, je "triche" en remplaçant les caractères accentués par leur equivalent non accentué en faisant un str_replace
Pour ton exemple , je ferais quelquechose comme :

$mot = "élève";
        $mot = str_replace(['à', 'â', 'ä', 'á', 'ã', 'å',
        'î', 'ï', 'ì', 'í', 
        'ô', 'ö', 'ò', 'ó', 'õ', 'ø', 
        'ù', 'û', 'ü', 'ú', 
        'é', 'è', 'ê', 'ë'],
        ['a', 'a', 'a', 'a', 'a', 'a', 
        'i', 'i', 'i', 'i', 
        'o', 'o', 'o', 'o', 'o', 'o', 
        'u', 'u', 'u', 'u', 
        'e', 'e', 'e', 'e'], $mot);
        $up =strtoupper($mot);
        $longueur=strlen($up);
        $reponse=str_repeat('_',$longueur);
        $reponse[0]=$up[0]; 
        $reponse[$longueur-1]=$up[$longueur-1]; 
        echo $response;   // affiche E___E
Default
,

Bonjour,
merci beaucoup pour ta réponse mais je me suis sans doute mal exprimé sur ce que je veux (je l'ai donc corrigé sur le post). Ce que je demande par "corriger l'affichage des accents sur le mot cherché dans la base de données", c'est que les accents s'affichent et me montre parfaitement "É _ _ _ E" à la fin.

Default
,

Alors essaie comme ceci :

$mot = 'élève';
        $up =mb_strtoupper($mot);  
        $longueur=mb_strlen($mot);
        $mask=str_repeat(' _ ',$longueur-2);  // on masque et on enleve 2 caractères représentant la première et la dernière lettre
        $reponse= mb_substr($up,0,1).$mask.mb_substr($up, $longueur-1 ,1); // on concatène la 1ère lettre , les caractères masqués et la dernière lettre 
        echo $reponse; //affiche É _ _ _ E  

En espérant avoir bien compris le problème cette fois ci :D

Default
,

Bonsoir, j'ai récemment programmé un pendu, qui fonctionne bien, mais j'aurais besoin de l'avis de personnes plus expérimentées que moi sur le code: la lisibilité/clarté, la logique, et la syntaxe du code.

Default
,

Merci beaucoup pour ton aide Thugg.
Grâce à toi j'y suis presque avec ces accents, il reste juste un problème que je ne comprends toujours pas.
Cela affiche parfaitement "É _ _ _ E" cependant lorsque que je sélectionne toutes les lettres pour constituer le mot élève ça fini en "É L ? _ E".
La lettre È fait apparaître un "?" et prends 2 caractères car la lettre "V" ne s'insère pas.

Si t'as une idée pour corriger ça je ne suis pas contre :D

Default
,

Bonsoir,
A mon avis ton problème vient de : $lettre= strtoupperFr($_POST['lettre']);
à remplacer par :

$lettre= mb_strtoupper($_POST['lettre']);  

Si ce n'est pas ça , il faudra que tu me dises ce que contient ta fonction Actualise_Reponse()

Un conseil amical : lis la doc php pour comprendre la différence entre strtoupper et mb_strtoupper . Comprendre ce qui nous bloque aide à progresser . C'est du moins ce que j'ai constaté sur moi quand j'ai commencé à apprendre à dev :D apprentissage toujours en cours d'ailleurs ^^ Merci grafikart !!

Default
,

Bonjour,
j'ai encore une fois fait une erreur en oubliant de préciser que j'avais bien modifié $lettre = strtoupperFr($_ POST['lettre']); par $lettre= mb_strtoupper($_ POST['lettre']); je suis désolé :(

Je t'envoie donc ma fonction Actualise_Reponse() :

function Actualise_Reponse($lettre)
{
  $i=0 ;
  $NbLettre=0 ;
  do
  {
    $i=strpos($_SESSION['mot'], $lettre, $i+1);
    if($i>0 && $i<($_SESSION['longueur'])-1){ // Assigne la réponse avec la lettre donnée
      $_SESSION['reponse'][$i]=$lettre ;
      $NbLettre++ ;
    }
  }
  while($i!==FALSE) ;
  /* Ajouter $lettre à la liste… */
  $_SESSION['liste'][]=$lettre ;
  return $NbLettre ;
}

Merci pour ton aide et je prends en considération tes conseils :D

Default
,

Bonjour,
un grand merci à toi Thugg ! C'est vrai, quelle plaie ces caractères multi-octets.
Ce que tu m'as donné marche à merveille, j'ai juste eu quelques difficultés parce-que je n'avais pas vu la disparition du $i+1 dans Actualise_Reponse() que j'ai corrigé.
Ca m'apprendra à ne pas bien lire ce qu'on me donne, je ferais plus attention à l'avenir.
Je comprends aussi mieux mb_strtoupper et mb_strpos, un peu de mal à comprendre ce que font utf8_encode et utf8_decode, je vais m'y intéresser.
En tout cas encore merci, pour tes réponses rapides, tes conseils et t'as su résoudre mes problèmes :D