Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Détecter UTF-8

17 réponses
Avatar
aski
Bonjour,

J'ai utilisé, pour détecter le codage UTF-8 dans un fichier (php, html ou
autre fichier texte), les fonctions API WideCharToMultiByte() et
MultiByteToWideChar() appelées successivement.
Cette méthode ne fonctionne évidemment que s'il existe des codes ASCII
supérieurs à 127.
Connaissez-vous d'autres axes de récherche en VB6 ?

Merci
--
Cordialement

Aski
MVP Windows Desktop Experience

7 réponses

1 2
Avatar
aski
Hello Fred et Jean-Marc,

"Fred" a écrit

Jean-marc écrivait :



Je confirme :o) Couplé avec une lecture binaire rapide si le fichier
n'est pas trop volumineux
(http://faq.vb.free.fr/index.php?question5), ce devrait être
extrèmement efficace !



Oui, mais contrairement à ce qui est proposé dans ton article (et pour ce
cas j'entends), je resterais en interprétation binaire. Soit à déclarer le
buffer en tableau d'octets et non en chaîne. Ce qui devrait d'ailleurs
diviser par deux l'espace mémoire utilisé. Et ensuite faciliter le
traitement des octets en effectuant des masquages binaires.
octet And 10000000 = 00000000 => caractère mono-octet
octet And 11100000 = 11000000 => premier octet d'un caractère sur deux
octets
octet And 11110000 = 11100000 => premier octet d'un caractère sur trois
octets
octet And 11111000 = 11110000 => premier octet d'un caractère sur quatre
octets
octet And 11000000 = 10000000 => octet de suite d'un caractère
multi-octets

Pour être complet, il y a des séquences non valides en UTF-8 qu'il
faudrait traiter mais je crois que l'article sur wikipedia y fait
référence. Sinon, voir par exemple ici :
http://www.ietf.org/rfc/rfc3629.txt



Merci à vous deux. Je prévois de tester les 2 méthodes dès que j'en aurai
terminé avec ma maçonnerie.
--
Cordialement

Aski
MVP Windows Desktop Experience
Avatar
aski
Hello Jean-Marc,

"Jean-marc" a écrit dans le message de groupe de
discussion : 48adcf7f$0$2856$
aski wrote:
Re,
Mais analyser le fichier en le lisant avec, pourquoi pas, un petit
automate d'état fini dont Jean-Marc a le secret, devrait être
extrêmement rapide !





Je confirme :o) Couplé avec une lecture binaire rapide si le fichier
n'est pas trop volumineux (http://faq.vb.free.fr/index.php?question5),
ce devrait être extrèmement efficace !

Je ne joue pas dans la même catégorie de Jean-Marc et je le regrette.
:-(



C'est trop d'honneur :-)

Rien de bien compliqué en soi dans les automates. Je pense que l'exemple
que j'ai indiqué dans la FAQ doit permettre de comprendre le principe:
http://faq.vb.free.fr/index.php?question3



Effectivement, il m'est arrivé de faire des automates sans le savoir ....
:o)

Une petite question : pourquoi utiliser
(InStr(validStates, Trim$(Str$(etat)) & ",") > 0)
et non
(etat =1 or etat =4) par exemple ?
Est-ce pour gagner de la vitesse ?
--
Cordialement

Aski
MVP Windows Desktop Experience
Avatar
jean-marc
"aski" wrote in message
news:
Hello Jean-Marc,



Hello Aski,

Une petite question : pourquoi utiliser
(InStr(validStates, Trim$(Str$(etat)) & ",") > 0)
et non
(etat =1 or etat =4) par exemple ?



C'est pour centraliser au début de la fonction la
description des états valides, dans une seule variable.

Ainsi, si on modifie l'automate et qu'on modifie les états
valides (ajout, suppression, modification, etc.) il suffit
de modifier la variable validStates.

On peut aussi avoir un automate plus grand avec plein d'états
finaux et alors ça évite une longue séquence de "OR".

Bref, c'est une question de lisibilité du code.

Est-ce pour gagner de la vitesse ?



Non :-)

Le (Instr + Trim + Str) est environ 700 fois plus lent
qu'un simple test avec un IF et des OR...

Mais au bout du compte, la différence est petite car ce
traitement final est petit comparé au reste...

Avec des If au lieu du Instr, on gagne plus ou
mois 1 microseconde par appel.

Il faut donc faire 1 million d'appels à la fonction
pour gagner une seconde.

Donc, à moins d'avoir des contraintes de performances
extrèmement sévères, dans un programme dont le seul
but est d'appeller cette fonction, plusieurs dizaines ou
centaines de millions de fois, ça ne fait pas différence.

Et on gagne à mon sens en lisibilité en utilisant la
forme avec Instr (ou avec toute forme d'écriture
similaire).

Cordialement,

--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
FAQ VB: http://faq.vb.free.fr/
mailto: remove '_no_spam_' ;
Avatar
aski
Re,

"jean-marc" a écrit dans le message de
groupe de discussion : 48b2c564$0$2848$

Ainsi, si on modifie l'automate et qu'on modifie les états
valides (ajout, suppression, modification, etc.) il suffit
de modifier la variable validStates.



... et également les Select Case, non ?

On peut aussi avoir un automate plus grand avec plein d'états
finaux et alors ça évite une longue séquence de "OR".



Bref, c'est une question de lisibilité du code.



Effectivement, dans ce cas, c'est plus "propre".

Donc, à moins d'avoir des contraintes de performances
Et on gagne à mon sens en lisibilité en utilisant la
forme avec Instr (ou avec toute forme d'écriture
similaire).



C'est vrai, mais j'ai quand-même dû décoder pour comprendre l'astuce.
--
Cordialement

Aski
MVP Windows Desktop Experience
Avatar
Jean-marc
aski wrote:
Re,



Ainsi, si on modifie l'automate et qu'on modifie les états
valides (ajout, suppression, modification, etc.) il suffit
de modifier la variable validStates.



... et également les Select Case, non ?



Oui, en effet :-)

On peut aussi avoir un automate plus grand avec plein d'états
finaux et alors ça évite une longue séquence de "OR".
Bref, c'est une question de lisibilité du code.





Effectivement, dans ce cas, c'est plus "propre".



Je trouve aussi.

Donc, à moins d'avoir des contraintes de performances
Et on gagne à mon sens en lisibilité en utilisant la
forme avec Instr (ou avec toute forme d'écriture
similaire).



C'est vrai, mais j'ai quand-même dû décoder pour comprendre l'astuce.



C'est vrai qu'un commentaire n'aurait pas été supeflu !

--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
FAQ VB: http://faq.vb.free.fr/
mailto: remove '_no_spam_' ;
Avatar
aski
Salut Fred,

Et ensuite faciliter le traitement des octets en effectuant des masquages
binaires.
octet And 10000000 = 00000000 => caractère mono-octet



OK, dans ce cas le type de codage est indéterminé.

octet And 11100000 = 11000000 => premier octet d'un caractère sur deux
octets
octet And 11110000 = 11100000 => premier octet d'un caractère sur trois
octets
octet And 11111000 = 11110000 => premier octet d'un caractère sur quatre
octets
octet And 11000000 = 10000000 => octet de suite d'un caractère
multi-octets



Il me semble qu'il ne devrait pas être nécessaire de lire cet octet
puisqu'on lit au préalable le nombre d'octets du caractère codé.

Pour être complet, il y a des séquences non valides en UTF-8 qu'il
faudrait traiter mais je crois que l'article sur wikipedia y fait
référence. Sinon, voir par exemple ici :
http://www.ietf.org/rfc/rfc3629.txt



J'ai également trouvé ce pdf dont le tableau 3-1B précise clairement les
codes valides
http://hapax.qc.ca/pdf/Chapitre-3.pdf
--
Cordialement

Aski
MVP Windows Desktop Experience
Avatar
Fred
"aski" a écrit dans le message de
news:
Salut Fred,

Et ensuite faciliter le traitement des octets en effectuant des
masquages
binaires.
octet And 10000000 = 00000000 => caractère mono-octet



OK, dans ce cas le type de codage est indéterminé.



C'est le caractère correspondant à la valeur de l'octet dans le jeu
ASCII (octets de 0 à 127)

octet And 11000000 = 10000000 => octet de suite d'un caractère
multi-octets



Il me semble qu'il ne devrait pas être nécessaire de lire cet octet
puisqu'on lit au préalable le nombre d'octets du caractère codé.



On cherche à savoir si le fichier est un fichier UTF-8, alors il faut au
moins vérifier que les deux bits de poids forts sont 1 et 0.

Cela constitue d'ailleurs un des avantages de l'UTF-8 : il est très
facile de se repositionner sur un début de séquence en cas de suite non
valide ou d'erreurs de lecture.

--
Fred

1 2