Partage
  • Partager sur Facebook
  • Partager sur Twitter

Int vers Char

Sujet résolu
    13 août 2011 à 21:19:32

    Bonjour,

    j'ai un petit problème qui me chagrine un peu. J'ai une liste de nombre entre 0 et 255 que je souhaite convertir en char (donc Int32 vers Char).

    Donc j'utilise la commande
    Convert.ToChar(monnombre)
    

    Jusque là, pas de problème. Le problème survient lors de la conversion de certains nombres particulièrement ceux situés entre 128 et 159 inclus.

    Voici une liste de tous les char obtenus à partir des nombres de 0 à 255 de chez MSDN ([url]http://msdn.microsoft.com/en-us/library/6c608ydz(v=vs.85).aspx[/url])

    Pour le int 128, on est censé obtenir le symbole suivant : € (euro). Or, j'obtiens toujours le symbole ? (point d'interrogation) pour chaque int de 128 à 159.

    Je ne vois pas d'où ça vient, puisqu'en plus ça fonctionne bien avec tous les int supérieurs à 159.

    En espérant que quelqu'un pourra m'aider. Merci d'avance.
    • Partager sur Facebook
    • Partager sur Twitter
      13 août 2011 à 22:31:59

      Un char est codé avec l'encodage UTF-16 dans lequel le code U+0080 (80 en base 16 = 128 en base 10) correspond au caractère PAD, qui n'est pas affichable.

      Si tu écris char c = '€'; tu vois à côté de c (en mode debug) 8364 (en base 10), qui fait 20AC en hexadécimal. Miracle U+20AC en UTF-16, c'est le caractère du symbole de l'euro. :)

      cf. : U+0080 et U+20AC.


      En fait la table de caractères que tu as trouvée est Windows-1252, dans laquelle le code 80 (en hexadécimal, donc 128 en base 10) représente le symbole de l'euro.
      • Partager sur Facebook
      • Partager sur Twitter
        13 août 2011 à 22:58:48

        Merci pour ces explications, mais je ne comprends pas alors pourquoi les nombres supérieurs à 159, passe bien lors de la conversion en char.

        Donc la solution serait de convertir chaque nombre en hexadécimal et ensuite les afficher ? Ou ça ne changera rien, les caractères ne seront pas affichables ?
        • Partager sur Facebook
        • Partager sur Twitter
          13 août 2011 à 23:13:54

          Il faut bien comprendre ce que tu fais : tu fais une conversion vers un char donc tu utilises l'encodage d'un char, à savoir UTF-16. En UTF-16, les caractères codés par les entiers de 128 à 159 (soit de 0080 à 009F en hexadécimal) ne sont pas affichables : cf. Wikipédia.

          La première question que tu dois te poser est la suivante :
          Quel encodage a utilisé celui qui a stocké ces nombres pour désigner des caractères ?


          Ensuite on pourra voir ce qu'il faut écrire pour afficher les caractères souhaités.
          • Partager sur Facebook
          • Partager sur Twitter
            13 août 2011 à 23:59:16

            L'encodage utilisé par défaut est unicode si je ne me trompe pas. Je ne touche pas à l'encodage entrant.
            • Partager sur Facebook
            • Partager sur Twitter
              14 août 2011 à 0:11:45

              Citation : vico63

              L'encodage utilisé par défaut est unicode si je ne me trompe pas. Je ne touche pas à l'encodage entrant.



              Ça ne répond pas à ma question. Qu'appelles-tu "encodage entrant" ? D'où viennent les nombres que tu utilises ?
              • Partager sur Facebook
              • Partager sur Twitter
                14 août 2011 à 0:18:41

                Je lis la ligne contenant les nombres à partir d'un fichier texte avec la méthode StreamReader. Il s'agit donc de l'encodage ANSI d'après NotePad++.
                • Partager sur Facebook
                • Partager sur Twitter
                  14 août 2011 à 0:27:08

                  La question n'est pas "comment lis-tu ces nombres ?", mais "comment ces nombres ont-ils été produits ?" :-°
                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 août 2011 à 0:31:29

                    Le principe des codages est que tu peux lire des données comme tu veux, mais pour que ça ait un sens il faut lire comme l'a pensé celui qui a écrit ces fameuses données.

                    Pourrais-tu nous mettre en ligne le fichier, histoire qu'on puisse faire des tests avec (regarder le BOM, torturer le fichier pour qu'il parle, ...) ?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 août 2011 à 0:37:17

                      Voici le lien du fichier (.txt) que je créé (toujours de la même façon, sous notepad++, sans rien modifier à l'enregistrement)

                      nombres.txt
                      • Partager sur Facebook
                      • Partager sur Twitter
                        14 août 2011 à 0:39:15

                        T'es sûr que ce sont des caractères ? o_O
                        Note que pour un fichier aussi court, il suffisait de copier son contenu ici... :-°

                        Pour ceux qui ont la flemme de télécharger:

                        Citation

                        127.243.128.75.32.148.37.222

                        • Partager sur Facebook
                        • Partager sur Twitter
                          14 août 2011 à 0:43:05

                          Citation : Orwell

                          T'es sûr que ce sont des caractères ? o_O



                          Au final je veux des caractères. A la base, c'est un string que je découpe (Split) par les '.' (point) pour obtenir des int que je transforme en char.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            14 août 2011 à 0:46:19

                            Si je comprends bien, tu as une string, tu la découpes, tu mets les morceaux dans un fichier texte, et tu ouvres ce fichier plus tard pour retrouver la string de départ ?

                            Si c'est le cas, donne-nous le code qui te permet d'écrire dans le fichier stp.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              14 août 2011 à 0:51:05

                              Non non non non :D

                              J'ai ce fichier texte à la base, écrit à la main par un éditeur (NotePad++). Par mon programme, je lis l'intégralité du fichier texte que je stock dans 1 string.

                              Ensuite je découpe cette string par les points '.' (méthode Split('.')).

                              Après je converti chaque int découpé (ce sont des string découpés à la base, mais avec la méthode Convert.ToInt32, ça devient un int) puis je converti chaque int en char (méthode Convert.ToChar).
                              • Partager sur Facebook
                              • Partager sur Twitter
                                14 août 2011 à 0:55:00

                                Oui mais les nombres qui ont été écrits dans ce fichier (à la main ou automatiquement, peu importe), ils sortent d'où ? :-°
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  14 août 2011 à 0:57:27

                                  De ma tête simplement, c'est juste pour tester les conversions, je me suis aperçu de ça, ça m'a intrigué, tout simplement. Et je voulais juste savoir si il y avait une solution.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    14 août 2011 à 1:07:51

                                    Mouais, c'est bien ce que je pensais. :lol:

                                    Il y a une solution, elle consiste à utiliser simplement une table de conversion int <-> char différente. Par défaut et comme l'a indiqué Narvarth, la table par défaut est UTF-16, et tous les caractères que tu peux obtenir à partir de tes nombres via cette table ne sont pas imprimables.

                                    Tu peux utiliser une autre table, par exemple la table Windows-1252 que Narvarth a citée:

                                    using System.Text;
                                    //...
                                    // ces bytes proviennent d'où tu veux
                                    byte[] bytes = new byte[] { 127, 243, 128, 75, 32, 148, 37, 222 };
                                    char[] chars = Encoding.GetEncoding("Windows-1252").GetChars(bytes);
                                    
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      14 août 2011 à 1:19:26

                                      Citation : vico63

                                      Non non non non :D

                                      J'ai ce fichier texte à la base, écrit à la main par un éditeur (NotePad++). Par mon programme, je lis l'intégralité du fichier texte que je stock dans 1 string.

                                      Ensuite je découpe cette string par les points '.' (méthode Split('.')).

                                      Après je converti chaque int découpé (ce sont des string découpés à la base, mais avec la méthode Convert.ToInt32, ça devient un int) puis je converti chaque int en char (méthode Convert.ToChar).



                                      En gros :
                                      • tu lis le contenu véritable de ton fichier (octets) ;
                                      • tu convertis ça en une chaîne de caractères : pour faire cette conversion (binaire -> string), tu utilises une table de codage dépendant de ta "localisation" ou "culture" qui doit être fr-FR, donc certainement Windows-1252 ou ISO-8859-1, ou dépendant de ce qui est écrit au début du fichier (BOM) ;
                                      • tu découpes ta chaîne en fonction de la position des points (pourquoi des points ?), tu obtiens des sous-chaînes ;
                                      • tu convertis chaque sous-chaîne chaînes en le nombre qu'elle représente (ex : "123" -> 123)
                                      • tu convertis ce nombre en caractère, grâce à l'UTF-16.

                                      En fait, ça n'a pas de sens à mes yeux. Que cherches-tu à faire réellement ?

                                      Il faut bien que tu comprennes que si tu écris des nombres dans un éditeur de texte, physiquement en mémoire ce ne seront pas ces nombres qui seront écrits, mais d'autres nombres qui, d'après une certaine table de caractères, leur correspondent.

                                      [EDIT:]
                                      Tout-à-l'heure, j'ai fais à la main la conversion en utilisant Windows-1252 et voilà le résultat :

                                      Nombre en base 10 127 243 128 75 32 148 37 222
                                      Nombre en base 16 7F F3 80 4B 20 94 25 DE
                                      Caractère correspondant DEL ó euro : € K espace guillemet spécial : ” % Þ
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        14 août 2011 à 1:24:08

                                        Merci bien, je vais voir ce que ça donne. J'éditerai ce message pour vous dire si vous avez résolu mon problème ou non ;)

                                        EDIT:

                                        Bon, ça ne change rien. Soit je n'utilise pas la bonne méthode pour lire le char soit... enfin ça vient surement de moi.

                                        J'utilise ce code (pour l'exemple, j'ai juste utilisé la valeur 128.
                                        byte[] nb = new byte[] { 128 };
                                                    char[] nb2 = Encoding.GetEncoding("Windows-1252").GetChars(nb);
                                                    string str = new string (nb2);
                                                    Console.WriteLine(str);
                                        


                                        Malgré cela, j'obtiens toujours le symbole ? et pas €.

                                        Narvarth, si tu pouvais me dire quelle méthode tu as employé pour obtenir le symbole € à partir de la valeur 128 car là, je bloque réellement.

                                        Merci d'avance ;)
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          14 août 2011 à 1:46:25

                                          Au fait, pendant qu'on y est :

                                          Citation : vico63

                                          Or, j'obtiens toujours le symbole ? (point d'interrogation) pour chaque int de 128 à 159.


                                          J'imagine que tu as essayé d'affiché tes caractères en console. Si c'est le cas, sache que la console Windows utilise la page de code 850 (si tu es en Europe Occidentale, ce qui me semble être le cas :-° ).

                                          Si tu cliques sur ce lien, tu auras la table des caractères utilisés pour l'affichage. Comme tu peux le constater, ils sont en nombre restreint, donc si tu demandes à la console de t'afficher un caractère en lui envoyant un code qu'elle ne connaît pas, elle affiche un simple point d'interrogation.

                                          [EDIT]En fait, elle utilise juste Windows-1252. La page de code 850 ne doit plus servir. Mais le principe est le même : le nombre de caractères codés est limité[/EDIT]

                                          Tu veux tester ? Écris ça dans un programme console :

                                          // 40 en hexadécimal sert à coder un arobase, d'après Windows-1252.
                                          char arobase = (char)0x40;
                                          Console.Write(arobase);
                                          
                                          // 1252
                                          int CP = Console.OutputEncoding.WindowsCodePage;
                                          // "ibm850"
                                          string webName = Console.OutputEncoding.WebName;
                                          
                                          // On met en pause.
                                          Console.Read();
                                          


                                          Surprise ! :magicien: Ça a bien affiché un arobase. :waw:

                                          Intéressant, n'est-il pas ?
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            14 août 2011 à 1:52:28

                                            Ca fonctionne ! Merci beaucoup à vous ! En effet, on a posté en même temps avec Narvarth, et j'ai vu qu'après le problème d'affichage console ;)

                                            Je vous remercie de l'aide que vous m'avez apporté et je m'excuse de la gêne occasionnée, surtout à cette heure là :p

                                            Bonne soirée et merci encore !
                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Int vers Char

                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                            • Editeur
                                            • Markdown