none
Problème de conversion caractère vers Ascii RRS feed

  • Question

  • Bonjour!

    J'ai un problème un peu débile dans mon dév' mais j'arrive pas à la résoudre alors pourquoi pas trouver un peu d'aide ici =)

    Je vous explique:
    Je récupère un fichier bourrés de caractères bizarres et j'ai besoin de les convertir en hexadécimal, je fais donc la chose suivante après récupération du fichier en question:

    Dim x(fileReader.Length) As Char

    Using sr As StringReader = New StringReader(fileReader)

    For i = 0 To fileReader.Length Step 1

    sr.Read(x, i, 1)
    x(i) = Hex(Asc(x(i)))

    Next i

    End Using


    Cela fonctionne plutôt bien mais j'ai le problème suivant, je prends un exemple:
    Je reçois en entrée le caractère "„" son code ASCII est 84 (en hexadécimal), Hex(Asc(x(i))) me donne bien ce code mais lorsque je range ce résultat dans x(i) on ne me stock uniquement le premier caractère hexadécimal, donc le 8 et je n'arrive pas à comprendre pourquoi le 84 en entier n'est pas stocké...

    J'espère m'être exprimer clairement et que quelqu'un pourra m'aider!
    Merci d'avance =))
    mercredi 29 août 2012 10:02

Réponses

  • Pour la classe Encoding ,d'après l'exemple en bas de page :

    Imports System.Text

    Pour les Api's, en VB6 c'était :

    Public Declare Function OemToCharBuff Lib "user32" Alias "OemToCharBuffA" (ByVal lpszSrc As String, _
                                                                                   ByVal lpszDst As String, _
                                                                                   ByVal cchDstLength As Long) As Long
    Public Declare Function CharToOemBuff Lib "user32" Alias "CharToOemBuffA" (ByVal lpszSrc As String, _
                                                                                   ByVal lpszDst As String, _
                                                                                   ByVal cchDstLength As Long) As Long
    

    Le compilateur .Net n'a pas l'air de râler, mais il faut tout de même un peu adapter (Long -> Int32) :

    Declare Function OemToCharBuff Lib "user32" Alias "OemToCharBuffA" (ByVal lpszSrc As String, _
                                                                            ByVal lpszDst As String, _
                                                                            ByVal cchDstLength As Int32) As Int32
    Declare Function CharToOemBuff Lib "user32" Alias "CharToOemBuffA" (ByVal lpszSrc As String, _
                                                                            ByVal lpszDst As String, _
                                                                            ByVal cchDstLength As Int32) As Int32
    
    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
            Dim lResult As Int32
            Dim Src As String, Dst As String
    
            Src = "é è ç à â ê î ô û ä ë ï ö ü ù"
            Dst = Space(Src.Length)
            lResult = CharToOemBuff(Src, Dst, Src.Length)
            MessageBox.Show("Ceci est une chaine Unicode : " & Src & vbCrLf & _
                            "Ceci est une chaine OEM     : " & Dst)
    End Sub

    Résultat :

    Ça ressemble un peu à   j'envoie "„" je reçois "ä" de l'autre côté... Pour "Š" je reçois "è", non ?


    Cordialement, Jacques

    • Proposé comme réponse Richard ClarkMVP jeudi 30 août 2012 15:12
    • Marqué comme réponse Michel K jeudi 30 août 2012 17:05
    jeudi 30 août 2012 14:04

Toutes les réponses

  • Bonjour,

    if vous faut une deuxieme variable qui va contenir le resultat, disons 'res' du type stringbuilder,

    alors que vous pouvez faire ceci:

    Dim x(fileReader.Length) As Char
    Dim res as new StringBuilder ' (dans system.text je pense)
    
    Using sr As StringReader = New StringReader(fileReader)
    
    For i = 0 To fileReader.Length - 1 Step 1
    
    sr.Read(x, i, 1)
    'x(i) = Hex(Asc(x(i)))
    res.append(Hex(Asc(x(i))))
    
    Next i
    
    End Using
    
    return res.ToString


    Regards, Nico

    mercredi 29 août 2012 10:29
  • Merci cela marche très bien, ce n'est pas tout à fait ce que je voulais cependant!

    Avec votre solution un code hexadécimal tient sur deux cases d'un tableau de char. N'y a-t-il pas moyen de faire tenir le code 0x84 (pour exemple) dans une seule case du tableau de char?

    mercredi 29 août 2012 11:34
  • Merci cela marche très bien, ce n'est pas tout à fait ce que je voulais cependant!

    Avec votre solution un code hexadécimal tient sur deux cases d'un tableau de char. N'y a-t-il pas moyen de faire tenir le code 0x84 (pour exemple) dans une seule case du tableau de char?

    Non, un string est un array de characteres, alors une postion , par example x(i), fait reference a un seul charactere.

    Regards, Nico

    mercredi 29 août 2012 13:03
  • Ok mais on est d'accord que le caractère "„" a pour code hexadécimal 0x84? Donc normalement on pourrait stocké dans un char 0x84 comme on peut stocker "„", non?
    mercredi 29 août 2012 13:19
  • Ok mais on est d'accord que le caractère "„" a pour code hexadécimal 0x84? Donc normalement on pourrait stocké dans un char 0x84 comme on peut stocker "„", non?

    Non, 

    un caractère prends 16 bit en memoire, et represente 1 seul caractère. Les 16 bit, on peut les representer binaire-ment, ou hexadecimale-ment, ou decimale-ment, mais ca reste le meme nombre. Ce nombre corresponds avec un caractere dans le table des caracteres unicode. La representation hexadecimale d'un tel nombre prends 4 caractères.

    http://msdn.microsoft.com/en-us/library/7sx7t66b(v=vs.71).aspx

    fin de leçon


    Regards, Nico


    • Modifié Nico Boey mercredi 29 août 2012 14:45
    mercredi 29 août 2012 14:43
  • Bonjour Lastagette,

    La fonction Hex renvoie une chaine caractère. Essaie ce code :

            Dim x(1) As Char
            Dim s As String
    
            ' En Décimal
            x(1) = Chr(132)
            MsgBox(x(1))
    
            ' En Hexa
            x(1) = Chr("&H84")
            MsgBox(x(1))
    
            ' En chaine => 2 caractères
            s = Hex(Asc(x(1)))
            MsgBox("Chaine = " & s & " (Longueur : " & s.Length & ")" & vbCrLf & _
                   "Hexa     = " & Hex(Asc(s(0))) & " " & Hex(Asc(s(1))))

    Hex renvoie bien deux caractères : "84" soit "0x38" et  "0x34"

    Je ne comprend d'ailleurs pas le but de : x(i) = Hex(Asc(x(i)))
    Quel est le problème avec les données telle qu'elles sont lues ?

    x(i) = "„"   c'est à dire 132 en décimal et 0x84 en Hexa. J'ai l'impression que si Hex fonctionnait comme tu le penses, cela ne servirait à rien : tu aurais toujours 0x84 sur un caractère (un octet) c'est à dire 132 en décimal, c'est à dire "„".


    Cordialement, Jacques

    mercredi 29 août 2012 14:45
  • Ben en fait le soucis que je dois transférer des caractères en ASCII étendue via le port série et je crois avoir tout essayé mais les caractères ASCII étendue que j'envoie ne sont pas ceux que je reçois...

    Pour exemple lorsque j'envoie "„" je reçois "ä" de l'autre côté... Pour "Š" je reçois "è", bref y'a aucune logique...



    jeudi 30 août 2012 08:19
  • Une petite question : votre fichier est-il bien en UTF8 ? Le StringReader utilise UTF8 par défaut si l'encodage n'est pas précisé.

    Richard Clark
    Consultant - Formateur .NET
    http://www.c2i.fr
    Depuis 1996: le 1er site .NET francophone

    jeudi 30 août 2012 09:23
  • J'ai mis le fichier en Default, c'était le seul qui me permettait de lire les codes ASCII étendues

    fileReader = My.Computer.FileSystem.ReadAllText(CommonDialog1.FileName, System.Text.Encoding.Default)

    Du côté du port série:

    SerialPort1.Encoding = System.Text.Encoding.Default

    jeudi 30 août 2012 09:50
  • Default = UTF8 pour le FileReader.

    Si je comprends bien, vous recevez le contenu de ce fichier par un port COM qui l'enregistre dans un fichier.

    Faites peut être des essais avec d'autres encodages pour voir.


    Richard Clark
    Consultant - Formateur .NET
    http://www.c2i.fr
    Depuis 1996: le 1er site .NET francophone

    jeudi 30 août 2012 09:57
  • Comme l'indique Richard Clark, il faut déterminer l'encodage de ton fichier "source", et l'encodage sous lequel tu veux l'utiliser. Quelques pistes :

    Ces deux api's étaient assez fréquemment utilisées en VB6 pour gérer l'encodage DOS <--> Windows. Il y a sous .Net la classe Encoding


    Cordialement, Jacques


    • Modifié Jacques93 jeudi 30 août 2012 10:29 Faute de frappe
    jeudi 30 août 2012 10:28
  • En fait je récupère ce fichier sur le pc et je dois l'écrire dans une flash embarqué sur une carte via le port série. J'ai essayé tous les encodages déjà aucun n'est convenable.

    Jacques ça à l'air intéressant ces fonctions, que dois-je importer pour les utiliser?

    jeudi 30 août 2012 12:00
  • Pour la classe Encoding ,d'après l'exemple en bas de page :

    Imports System.Text

    Pour les Api's, en VB6 c'était :

    Public Declare Function OemToCharBuff Lib "user32" Alias "OemToCharBuffA" (ByVal lpszSrc As String, _
                                                                                   ByVal lpszDst As String, _
                                                                                   ByVal cchDstLength As Long) As Long
    Public Declare Function CharToOemBuff Lib "user32" Alias "CharToOemBuffA" (ByVal lpszSrc As String, _
                                                                                   ByVal lpszDst As String, _
                                                                                   ByVal cchDstLength As Long) As Long
    

    Le compilateur .Net n'a pas l'air de râler, mais il faut tout de même un peu adapter (Long -> Int32) :

    Declare Function OemToCharBuff Lib "user32" Alias "OemToCharBuffA" (ByVal lpszSrc As String, _
                                                                            ByVal lpszDst As String, _
                                                                            ByVal cchDstLength As Int32) As Int32
    Declare Function CharToOemBuff Lib "user32" Alias "CharToOemBuffA" (ByVal lpszSrc As String, _
                                                                            ByVal lpszDst As String, _
                                                                            ByVal cchDstLength As Int32) As Int32
    
    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
            Dim lResult As Int32
            Dim Src As String, Dst As String
    
            Src = "é è ç à â ê î ô û ä ë ï ö ü ù"
            Dst = Space(Src.Length)
            lResult = CharToOemBuff(Src, Dst, Src.Length)
            MessageBox.Show("Ceci est une chaine Unicode : " & Src & vbCrLf & _
                            "Ceci est une chaine OEM     : " & Dst)
    End Sub

    Résultat :

    Ça ressemble un peu à   j'envoie "„" je reçois "ä" de l'autre côté... Pour "Š" je reçois "è", non ?


    Cordialement, Jacques

    • Proposé comme réponse Richard ClarkMVP jeudi 30 août 2012 15:12
    • Marqué comme réponse Michel K jeudi 30 août 2012 17:05
    jeudi 30 août 2012 14:04
  • Merci beaucoup Jacques tu as parfaitement résolu mon problème et je t'en remercie =)
    jeudi 30 août 2012 14:48
  • J'ai marqué sa réponse comme "Réponse" ;-) Merci de le faire la prochaine fois.

    Richard Clark
    Consultant - Formateur .NET
    http://www.c2i.fr
    Depuis 1996: le 1er site .NET francophone

    jeudi 30 août 2012 15:12
  • Pour préciser, tu peux regarder :

    CodePage1252  et CodePage850

    où l'on voit que le caractère Hexa 0x84 (132 décimal) = "„" en CodePage 1252  et   "ä" en CodePage 850

    Merci de signaler comme résolu :-)


    Cordialement, Jacques

    jeudi 30 août 2012 15:18
  • Merci :-)

    Cordialement, Jacques

    jeudi 30 août 2012 15:21