Page 1 sur 1
Problème compréhension Unicode et PokeS
Publié : sam. 02/sept./2017 13:32
par Stefou
Bonjour à tous
Je tente d'adapter et donc de comprendre les changements de PB5.6 et particulièrement l'UNICODE
Et je ne comprends pas pourquoi lorsque je fais un POKES avec l'option #PB_ASCII, l'écriture en mémoire est sur 2 byte par caractères....
Le code suivant donne en mémoire 1.2.3.4.1.2.3.4. alors que j'aurais tendance à attendre 12341.2.3.4.
Merci d'avance pour avoir pris le temps de me lire
Code : Tout sélectionner
*MemoireID = AllocateMemory(500)
Debug *MemoireID
SetClipboardText(Str(*MemoireID))
If *MemoireID
PokeS(*MemoireID, "1234",#PB_Ascii)
PokeS(*MemoireID+8, "1234")
ShowMemoryViewer(*MemoireID, 16) ; Affiche l'adresse du tampon suivi de 48 E9 6C E9 00
CallDebugger
FreeMemory(*MemoireID)
Else
Debug "Impossible d'allouer la mmoire demande !"
EndIf
Re: Problème compréhension Unicode et PokeS
Publié : sam. 02/sept./2017 13:44
par Zorro
Pb travail en unicode
donc tout les caracteres prennent au minimum 2 Octets !
j'ai ecrit au minimum, car certains peuvent prendre jusqu'a 3,ou 4 octets !! (voir les caracteres etranger , Japonais, chinois etc )
comme je l'ai recemment signalé (pour mon convertisseur UTF8->Ascii
les 127 premiers caracteres Unicode sont les memes que les Caracteres Ascii !
mais en Unicode il y a un octet suplémentaire , pour garder la norme, egale a zero !
donc la representation est xx00 xx= le code ascii , et 00 octet reservé pour les caracteres de code supérieur a 127
lorsque les caracteres sont supérieur a 127 l'ecriture deviens :
xxYY
xx= le code Page genre "C3" ou "C5"
YY= le code Ascii si inferieur a 256

Re: Problème compréhension Unicode et PokeS
Publié : sam. 02/sept./2017 13:59
par Stefou
Merci Zorro
mais alors à quoi sert l'option: #PB_Ascii dans PokeS(*MemoireID, "1234",#PB_Ascii) ???
Re: Problème compréhension Unicode et PokeS
Publié : sam. 02/sept./2017 14:05
par Zorro
je suppose a calibrer "Borner" le caractere (l'octet ) a Maximum 255
pour revenir au sujet voici un petit code qui te montre comment decoder et passer du code en Ascii
(j'ai fait un code plus elaboré recemment sur le Forum )
http://www.purebasic.fr/french/viewtopi ... =6&t=16916
mais ça te donnera une idée de ce qui se passe ..
Code : Tout sélectionner
*MemoireID = AllocateMemory(500)
Debug *MemoireID
SetClipboardText(Str(*MemoireID))
If *MemoireID
car.s="é" ; <-- code "é" en UTF8
PokeS(*MemoireID,car.s,#Pb_UTF8)
ShowMemoryViewer(*MemoireID, 16) ; Affiche l'adresse du tampon puis les Words <<---- n'affiche pas le décodage ....
; pour afficher le decodage il faut faire :
Debug "Le caractere est : "+ Chr( PeekA(*MemoireID+2)+64 ) ; on lit le Deuxieme Word et on ajoute 64
FreeMemory(*MemoireID)
Else
Debug "Impossible d'allouer la mmoire demande !"
EndIf
Re: Problème compréhension Unicode et PokeS
Publié : sam. 02/sept./2017 14:33
par Stefou
je suppose a calibrer "Borner" le caractere (l'octet ) a Maximum 255
Ouai ouai, ce me semble ca aussi...
Bon du coup j'ai rajouter cette fonction:
Code : Tout sélectionner
Procedure PokeS_Ascci(addresse,ligne$,rien=0)
*asc=Ascii(ligne$)
CopyMemory(*asc ,addresse, Len(ligne$))
FreeMemory(*asc)
EndProcedure
Re: Problème compréhension Unicode et PokeS
Publié : lun. 04/sept./2017 11:11
par Mesa
Il existe déjà une fonction pb pour mettre une chaine ascii en memoire, c'est ASCII() !
Le buffer est créé automatiquement.
Code : Tout sélectionner
*Ascii = Ascii("Hélé")
ShowMemoryViewer(*Ascii, MemorySize(*Ascii)) ; Affiche l'adresse du tampon suivi de 48 E9 6C E9 00
Debug PeekS(*Ascii, -1, #PB_Ascii) ; Affiche "Hélé"
M.
Re: Problème compréhension Unicode et PokeS
Publié : lun. 04/sept./2017 14:32
par Zorro
lisez attentivement les commentaires :
Code : Tout sélectionner
Declare.s utf8toascii(ttx.s,mode)
;;*Ascii = Ascii("Hélé") <<<< ceci ne transforme pas de l'unicode en Ascii , ça creer simplement un pointeur sur une chaine qui est Ascii deja a la base .....
*UTF8 =UTF8("Hélé") ; mais si on part d'une chaine qui n'est pas AScii mais UTF8 ça ne marche pas !
ShowMemoryViewer(*UTF8, MemorySize(*UTF8)) ;
Debug PeekS(*UTF8, -1, #PB_Ascii) ; essaye d'Affiche "Hélé" au format Ascii ....marche pas ! ça affiche "Hélé"
; pareille si tu fais :
*Ascii = Ascii("Hélé")
Debug PeekS(*ascii, -1, #PB_Ascii)
; La seule Alternative pour Transformer de L'unicode (UTF8) en Ascii c'est de DECODER la chaine !
; comme ceci :
Vraie_chaine_Ascii.s=UTF8toAscii(Peeks(*Ascii) ,#true)
debug "une Vraie chaine Ascii -> " +Vraie_chaine_Ascii.s
;- Zone Procedures
Procedure.s UTF8toAscii(ttx.s,Mode)
; by Zorro / Dobro
Protected Sortie.s="" ,decal=1 ,i,Long
If Mode=#true ; travail en memoire
Long=Len(ttx.s)*2 ; on prevoi un peu large !
Else ; Travail sur caractere
Long=Len(ttx.s)+1
Endif
For i=0 to long
If Mode=#True ; travail sur memoire
Code.c=PeekA(@ttx.s+i)
Else
Code.c=Asc(Mid(ttx.s,i+decal,1))
Endif
IF Code<127
Sortie.s=Sortie.s+chr(Code.c)
Else
; Traitement .
If Mode=#True ; Travail sur memoire
Code1.c=PeekA(@ttx.s+i)
Code2.c=PeekA(@ttx.s+i+1)
Else
Code1.c=Asc(Mid(ttx.s,i+decal,1))
Code2.c=Asc(Mid(ttx.s,i+decal+1,1))
Endif
; Verif
Sortie.s=Sortie.s+chr(Code2.c+64)
i=i+1
Endif
Next i
ProcedureReturn Sortie.s
EndProcedure
Re: Problème compréhension Unicode et PokeS
Publié : lun. 04/sept./2017 16:11
par djes
Zorro a écrit :lisez attentivement les commentaires :
Code : Tout sélectionner
Declare.s utf8toascii(ttx.s,mode)
;;*Ascii = Ascii("Hélé") <<<< ceci ne transforme pas de l'unicode en Ascii , ça creer simplement un pointeur sur une chaine qui est Ascii deja a la base .....
*UTF8 =UTF8("Hélé") ; mais si on part d'une chaine qui n'est pas AScii mais UTF8 ça ne marche pas !
ShowMemoryViewer(*UTF8, MemorySize(*UTF8)) ;
Debug PeekS(*UTF8, -1, #PB_Ascii) ; essaye d'Affiche "Hélé" au format Ascii ....marche pas ! ça affiche "Hélé"
; pareille si tu fais :
*Ascii = Ascii("Hélé")
Debug PeekS(*ascii, -1, #PB_Ascii)
; La seule Alternative pour Transformer de L'unicode (UTF8) en Ascii c'est de DECODER la chaine !
; comme ceci :
Vraie_chaine_Ascii.s=UTF8toAscii(Peeks(*Ascii) ,#true)
debug "une Vraie chaine Ascii -> " +Vraie_chaine_Ascii.s
;- Zone Procedures
Procedure.s UTF8toAscii(ttx.s,Mode)
; by Zorro / Dobro
Protected Sortie.s="" ,decal=1 ,i,Long
If Mode=#true ; travail en memoire
Long=Len(ttx.s)*2 ; on prevoi un peu large !
Else ; Travail sur caractere
Long=Len(ttx.s)+1
Endif
For i=0 to long
If Mode=#True ; travail sur memoire
Code.c=PeekA(@ttx.s+i)
Else
Code.c=Asc(Mid(ttx.s,i+decal,1))
Endif
IF Code<127
Sortie.s=Sortie.s+chr(Code.c)
Else
; Traitement .
If Mode=#True ; Travail sur memoire
Code1.c=PeekA(@ttx.s+i)
Code2.c=PeekA(@ttx.s+i+1)
Else
Code1.c=Asc(Mid(ttx.s,i+decal,1))
Code2.c=Asc(Mid(ttx.s,i+decal+1,1))
Endif
; Verif
Sortie.s=Sortie.s+chr(Code2.c+64)
i=i+1
Endif
Next i
ProcedureReturn Sortie.s
EndProcedure
Code à tester en mode debug et en pas à pas pour comprendre la logique interne de conversion : les chaînes PB sont stockées en unicode ; il faut repasser par ce format pour effectuer les conversions.
Code : Tout sélectionner
machaineunicode.s = "Hélé"
taille = StringByteLength(machaineunicode)
Debug PeekS(@machaineunicode, taille, #PB_Unicode)
ShowMemoryViewer(@machaineunicode, taille)
CallDebugger
*machaineascii = Ascii(machaineunicode) ; Ici, la chaîne unicode est convertie en ASCII
ShowMemoryViewer(*machaineascii, MemorySize(*machaineascii))
Debug PeekS(*machaineascii, -1, #PB_Ascii)
CallDebugger
*machaineutf8 = UTF8(machaineunicode) ; Ici, la chaîne unicode est convertie en UTF8
Debug PeekS(*machaineutf8, SizeOf(*machaineutf8), #PB_UTF8)
ShowMemoryViewer(*machaineutf8, taille)
CallDebugger
machaineunicode = PeekS(*machaineascii, SizeOf(*machaineascii), #PB_Ascii) ; Ici, la chaîne ASCII est convertie en Unicode
taille = StringByteLength(machaineunicode)
Debug PeekS(@machaineunicode, taille, #PB_Unicode)
ShowMemoryViewer(@machaineunicode, taille)
CallDebugger
machaineunicode = PeekS(*machaineutf8, SizeOf(*machaineutf8), #PB_UTF8) ; Ici, la chaîne UTF8 est convertie en Unicode
taille = StringByteLength(machaineunicode)
Debug PeekS(@machaineunicode, taille, #PB_Unicode)
ShowMemoryViewer(@machaineunicode, taille)
Re: Problème compréhension Unicode et PokeS
Publié : lun. 04/sept./2017 19:57
par Zorro
ps: t'etais pas obliger de citer tout mon code ...
lis et essaye ça
Code : Tout sélectionner
machaineAscii.s = chr($48)+chr($E9)+chr($6C)+chr($E9) ; on fabrique une vraie chaine ASCII
machaineutf8.s="Hélé" ; <<<--- ceci est une VRAIE chaine UTF8
*machaineascii = Ascii(machaineutf8.s) ; Ici, la chaîne est sensé etre convertie en ASCII
ShowMemoryViewer(*machaineascii, MemorySize(*machaineascii))
Debug PeekS(*machaineascii, -1, #PB_Ascii) ; ce n'est pas le cas, elle affiche toujours "Hélé" ...... elle n'est pas décodée !!! alors qe ma procedure DECODE ;)
; ma procedure fait une Vraie conversion UTF8 ---> ASCII puisqu'elle effectue un DECODAGE de la chaine ...
CallDebugger
*machaineutf8 = UTF8(machaineAscii.s) ; Ici, la chaîneAscii est convertie en UTF8 <<<<<--- NON CAR
taille = StringByteLength(machaineAscii.s)
Debug PeekS(*machaineutf8, SizeOf(*machaineutf8), #PB_UTF8) ; ça devrai dans ce cas afficher "Hélé" dans le debugger , et ce n'esst pas le cas
ShowMemoryViewer(*machaineutf8, taille)
CallDebugger
Re: Problème compréhension Unicode et PokeS
Publié : lun. 04/sept./2017 21:06
par djes
Zorro a écrit :ps: t'etais pas obliger de citer tout mon code ...
lis et essaye ça
Code : Tout sélectionner
machaineAscii.s = chr($48)+chr($E9)+chr($6C)+chr($E9) ; on fabrique une vraie chaine ASCII
machaineutf8.s="Hélé" ; <<<--- ceci est une VRAIE chaine UTF8
*machaineascii = Ascii(machaineutf8.s) ; Ici, la chaîne est sensé etre convertie en ASCII
ShowMemoryViewer(*machaineascii, MemorySize(*machaineascii))
Debug PeekS(*machaineascii, -1, #PB_Ascii) ; ce n'est pas le cas, elle affiche toujours "Hélé" ...... elle n'est pas décodée !!! alors qe ma procedure DECODE ;)
; ma procedure fait une Vraie conversion UTF8 ---> ASCII puisqu'elle effectue un DECODAGE de la chaine ...
CallDebugger
*machaineutf8 = UTF8(machaineAscii.s) ; Ici, la chaîneAscii est convertie en UTF8 <<<<<--- NON CAR
taille = StringByteLength(machaineAscii.s)
Debug PeekS(*machaineutf8, SizeOf(*machaineutf8), #PB_UTF8) ; ça devrai dans ce cas afficher "Hélé" dans le debugger , et ce n'esst pas le cas
ShowMemoryViewer(*machaineutf8, taille)
CallDebugger
Je ne suis pas devant un ordi, mais je peux te dire que dès la première ligne, ça me semble faux, tout simplement parce que les chr() vont renvoyer de l'unicode. De même, la seconde ne sera pas un utf8, mais de l'unicode, avec une série de caractères alambiquées. Regarde en mémoire... Moi, je verrai demain ! Bonne nuit
Edit :
Voilà, j'ai regardé. Un petit code pour montrer ce qui se passe vraiment en mémoire...
Code : Tout sélectionner
mafaussechaineAscii.s = Chr($48)+Chr($E9)+Chr($6C)+Chr($E9) ; on fabrique une fausse chaine ASCII
CallDebugger
ShowMemoryViewer(@mafaussechaineAscii, StringByteLength(mafaussechaineAscii))
mafaussechaineutf8.s="Hélé" ; <<<--- ceci N'est PAS une VRAIE chaine UTF8
CallDebugger
ShowMemoryViewer(@mafaussechaineutf8, StringByteLength(mafaussechaineutf8))
PS: Je cite pour éviter les effacements intempestifs (pas forcément de l'auteur) qui font que certains sujets sont remplis de trous et du coup, on ne comprend plus la démarche.
Re: Problème compréhension Unicode et PokeS
Publié : mar. 05/sept./2017 8:24
par PAPIPP
Bonjour à tous
et comme ceci c'est tout bon
Code : Tout sélectionner
*MemoireID = AllocateMemory(500)
Debug *MemoireID
SetClipboardText(Str(*MemoireID))
If *MemoireID
PokeS(*MemoireID, "1234",4,#PB_Ascii) ;;; N'oubliez pas la longueur en ASCII
PokeS(*MemoireID+8, "1234")
ShowMemoryViewer(*MemoireID, 16) ; Affiche l'adresse du tampon suivi de 48 E9 6C E9 00
CallDebugger
FreeMemory(*MemoireID)
Else
Debug "Impossible d'allouer la mmoire demande !"
EndIf
PS : n'oubliez pas la longueur en ASCII sinon il reste en unicode
Syntaxe
Resultat = PokeS(*Memoire, Texte$ [, Longueur [, Options]])
A+
Re: Problème compréhension Unicode et PokeS
Publié : mar. 05/sept./2017 8:55
par djes
PAPIPP a écrit :Bonjour à tous
et comme ceci c'est tout bon
Code : Tout sélectionner
*MemoireID = AllocateMemory(500)
Debug *MemoireID
SetClipboardText(Str(*MemoireID))
If *MemoireID
PokeS(*MemoireID, "1234",4,#PB_Ascii) ;;; N'oubliez pas la longueur en ASCII
PokeS(*MemoireID+8, "1234")
ShowMemoryViewer(*MemoireID, 16) ; Affiche l'adresse du tampon suivi de 48 E9 6C E9 00
CallDebugger
FreeMemory(*MemoireID)
Else
Debug "Impossible d'allouer la mmoire demande !"
EndIf
PS : n'oubliez pas la longueur en ASCII sinon il reste en unicode
Syntaxe
Resultat = PokeS(*Memoire, Texte$ [, Longueur [, Options]])
A+
Merci PAPIPP, voici deux petites procédures vite faites (à vérifier STP) en application de ce que tu dis.
Code : Tout sélectionner
Procedure.i Unicode2ASC(string.s)
If Len(string) <= 0
Debug "String is empty"
ProcedureReturn #False
EndIf
*asciibuffer = AllocateMemory(Len(string) + 1)
If *asciibuffer
PokeS(*asciibuffer, string, Len(string), #PB_Ascii) ; Don't forget ASCII length
Else
Debug "Can't allocate needed memory"
ProcedureReturn #False
EndIf
ProcedureReturn *asciibuffer
EndProcedure
Procedure.s Asc2Unicode(*string)
If *string = 0 Or MemorySize(*string) <= 0
Debug "String is empty"
ProcedureReturn ""
EndIf
ProcedureReturn PeekS(*string, MemorySize(*string) - 1, #PB_Ascii)
EndProcedure
;- MAIN
OpenConsole()
NativeUnicodeString.s = "hélé"
PrintN(NativeUnicodeString)
*ConvertedASCIIString = Unicode2ASC(NativeUnicodeString.s)
PrintN(Asc2Unicode(*ConvertedASCIIString))
ShowMemoryViewer(*ConvertedASCIIString, MemorySize(*ConvertedASCIIString))
CallDebugger
FreeMemory(*ConvertedASCIIString) ; Don't forget to free ASCII memory buffer