Problème compréhension Unicode et PokeS

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Stefou
Messages : 234
Inscription : jeu. 18/janv./2007 14:08

Problème compréhension Unicode et PokeS

Message 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
  
  
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: Problème compréhension Unicode et PokeS

Message 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

:)
Stefou
Messages : 234
Inscription : jeu. 18/janv./2007 14:08

Re: Problème compréhension Unicode et PokeS

Message par Stefou »

Merci Zorro

mais alors à quoi sert l'option: #PB_Ascii dans PokeS(*MemoireID, "1234",#PB_Ascii) ???
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: Problème compréhension Unicode et PokeS

Message 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
 
  
Stefou
Messages : 234
Inscription : jeu. 18/janv./2007 14:08

Re: Problème compréhension Unicode et PokeS

Message 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
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: Problème compréhension Unicode et PokeS

Message 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.
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: Problème compréhension Unicode et PokeS

Message 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
  
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Problème compréhension Unicode et PokeS

Message 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)

Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: Problème compréhension Unicode et PokeS

Message 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
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Problème compréhension Unicode et PokeS

Message 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.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Problème compréhension Unicode et PokeS

Message 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+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Problème compréhension Unicode et PokeS

Message 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
Répondre