Lecture de caractères ASCII à partir d'un fichier
-
- Messages : 41
- Inscription : mer. 30/déc./2009 10:11
Lecture de caractères ASCII à partir d'un fichier
Bonjour,
J'écris des caractère ASCII dans un fichier à l'aide de la commande WriteString(fichier_bd_id, v_bd , #PB_Ascii).
Cette commande fonctionne puisque lorsque je visualise le contenu du fichier créé, tout parait normal.
J'essaie ensuite de lire le contenu de ce fichier dans un tableau en mémoire interne.
Je lis le contenu de ce fichier caractère par caractère que je place dans les lignes du tableau avec la commande suivante:
t_clients(nbe)\prenom = t_clients(nbe)\prenom + Chr(ReadAsciiCharacter(fichier_import_id))
Lorsque je visualise le contenu du tableau, je remarque que les caractères accentués (é, è, à, ç ...) ne sont pas bien passés.
Par exemple, le caractère é est affiché é
Je visualise le contenu du tableau à l'aide du visualiseur de variable du débogeur de l'IDE de purebasic.
Il ne me semble pas que ce soit un problème lié au visualiseur de variable de purebasic car j'ai assigné à une variable une chaîne de caractères qui contient uniquement des caractères accentués et le contenu de cette variable s'affiche correctement.
Le tableau dans lequel je charge le contenu du fichier est définit comme suit:
Structure s_client
nom.s{30}
prenom.s{30}
rue.s{60}
numero.s{10}
ville.s{20}
cp.s{5}
pays.s{20}
EndStructure
Global Dim t_clients.s_client(nb_client_max-1)
Dernière précision, je travaille sous linux. Mais je ne vois pas en quoi cela pourrait être la source du problème.
Comment faire pour résoudre ce problème de caractères accentués?
Merci.
J'écris des caractère ASCII dans un fichier à l'aide de la commande WriteString(fichier_bd_id, v_bd , #PB_Ascii).
Cette commande fonctionne puisque lorsque je visualise le contenu du fichier créé, tout parait normal.
J'essaie ensuite de lire le contenu de ce fichier dans un tableau en mémoire interne.
Je lis le contenu de ce fichier caractère par caractère que je place dans les lignes du tableau avec la commande suivante:
t_clients(nbe)\prenom = t_clients(nbe)\prenom + Chr(ReadAsciiCharacter(fichier_import_id))
Lorsque je visualise le contenu du tableau, je remarque que les caractères accentués (é, è, à, ç ...) ne sont pas bien passés.
Par exemple, le caractère é est affiché é
Je visualise le contenu du tableau à l'aide du visualiseur de variable du débogeur de l'IDE de purebasic.
Il ne me semble pas que ce soit un problème lié au visualiseur de variable de purebasic car j'ai assigné à une variable une chaîne de caractères qui contient uniquement des caractères accentués et le contenu de cette variable s'affiche correctement.
Le tableau dans lequel je charge le contenu du fichier est définit comme suit:
Structure s_client
nom.s{30}
prenom.s{30}
rue.s{60}
numero.s{10}
ville.s{20}
cp.s{5}
pays.s{20}
EndStructure
Global Dim t_clients.s_client(nb_client_max-1)
Dernière précision, je travaille sous linux. Mais je ne vois pas en quoi cela pourrait être la source du problème.
Comment faire pour résoudre ce problème de caractères accentués?
Merci.
Re: Lecture de caractères ASCII à partir d'un fichier
C'est évidemment un problème avec l'Unicode. Il y a eu récemment un très bon papier sur le forum anglais à ce sujet : http://www.joelonsoftware.com/articles/Unicode.html (et le topic est là : http://www.purebasic.fr/english/viewtop ... =7&t=40634)
En clair et pour les francophones, il faut décourager la pratique ancestrale d'usage de pseudos ASCII et passer à l'Unicode (vraiment!). On a de la chance, PB fait ça très bien! Par contre il faut faire gaffe et ne pas faire de la lecture octet par octet, mais plutôt utiliser des instructions comme ReadUnicodeCharacter() et WriteUnicodeCharacter pour avoir des tailles fixes (2 octets par caractère).
En clair et pour les francophones, il faut décourager la pratique ancestrale d'usage de pseudos ASCII et passer à l'Unicode (vraiment!). On a de la chance, PB fait ça très bien! Par contre il faut faire gaffe et ne pas faire de la lecture octet par octet, mais plutôt utiliser des instructions comme ReadUnicodeCharacter() et WriteUnicodeCharacter pour avoir des tailles fixes (2 octets par caractère).
-
- Messages : 41
- Inscription : mer. 30/déc./2009 10:11
Re: Lecture de caractères ASCII à partir d'un fichier
Bon, j'ai remplacé les WriteString(fichier_bd_id, v_bd , #PB_Ascii) par WriteString(fichier_bd_id, v_bd , #PB_Unicode)
Le fichier généré n'est maintenant plus lisible dans un éditeur tel que vim par exemple.
Cela me parait normal.
Je fais maintenant les lectures avec t_clients(nbe)\nom = t_clients(nbe)\nom + Chr(ReadUnicodeCharacter(fichier_import_id))
J'ai toujours le même problème lorsque j'affiche le contenu de mon tableau.
Le fichier généré n'est maintenant plus lisible dans un éditeur tel que vim par exemple.
Cela me parait normal.
Je fais maintenant les lectures avec t_clients(nbe)\nom = t_clients(nbe)\nom + Chr(ReadUnicodeCharacter(fichier_import_id))
J'ai toujours le même problème lorsque j'affiche le contenu de mon tableau.
Re: Lecture de caractères ASCII à partir d'un fichier
Pourquoi tu mets chr() ? Et ta structure doit contenir des chaines unicode (.c ou .u)
Regarde la doc de ReadStringFormat() et de ReadString()
Regarde la doc de ReadStringFormat() et de ReadString()
-
- Messages : 41
- Inscription : mer. 30/déc./2009 10:11
Re: Lecture de caractères ASCII à partir d'un fichier
Si je lis des données en provenance d'un fichier excel de type .cvs avec la commande ReadString(fichier_import_id,#PB_Ascii), je remarque que les caractères accentués sont mal lus.
Si je lis ces mêmes données avec la commande ReadString(fichier_import_id,#PB_UTF8), les caractères accentués sont bien importés.
Si je lis ces mêmes données avec la commande ReadString(fichier_import_id,#PB_Unicode), l'importation se passe mal.
Après avoir lu avec succès les chaînes de caractères dans le format UTF8, je les réécris dans un fichier à l'aide de la commande WriteString(fichier_bd_id, v_bd , #PB_Ascii). Je les réécris donc en Ascii.
Par après, en utilisant la commande ReadAsciiCharacter(fichier_import_id), les caractères accentués sont bien lus.
Donc, la lecture en mode Ascii d'un fichier produit par excel ne laisse pas passer les caractères accentués.
La lecture en mode UTF8 d'un fichier excel laisse passer les caractères accentués.
Par contre, la lecture en mode Ascii d'un fichier produit par des commandes d'écriture (en mode Ascii) purebasic laisse passer les caractères accentués.
Je ne comprend pas pourquoi?
Si je lis ces mêmes données avec la commande ReadString(fichier_import_id,#PB_UTF8), les caractères accentués sont bien importés.
Si je lis ces mêmes données avec la commande ReadString(fichier_import_id,#PB_Unicode), l'importation se passe mal.
Après avoir lu avec succès les chaînes de caractères dans le format UTF8, je les réécris dans un fichier à l'aide de la commande WriteString(fichier_bd_id, v_bd , #PB_Ascii). Je les réécris donc en Ascii.
Par après, en utilisant la commande ReadAsciiCharacter(fichier_import_id), les caractères accentués sont bien lus.
Donc, la lecture en mode Ascii d'un fichier produit par excel ne laisse pas passer les caractères accentués.
La lecture en mode UTF8 d'un fichier excel laisse passer les caractères accentués.
Par contre, la lecture en mode Ascii d'un fichier produit par des commandes d'écriture (en mode Ascii) purebasic laisse passer les caractères accentués.
Je ne comprend pas pourquoi?
Re: Lecture de caractères ASCII à partir d'un fichier
Faudrait vraiment que tu lises une doc sur l'Unicode.
Pour faire court, en ASCII, un caractère est codé sur un octet. Pour des raisons historiques, seuls les 7 premiers bits (donc les 128 premiers caractères) sont 'à peu près' sûrs, le reste peut changer d'un pays à l'autre, d'une console à l'autre, etc. Or, les caractères accentués étaient gérés dans ce reste.
Donc, on change tout, il y a maintenant l'Unicode, chouette, on a maintenant (au moins) deux octets par caractère, on va pouvoir avoir 65536 possibilités. Mouaich, sauf que y'en a qui se sont dit que ça prenait de la place, deux octets par caractère! Donc, on a créé l'UTF8 qui encode parfois sur 1 octet (les 7 premiers bits!) et est donc "apparemment" compatible avec l'ASCII; sauf que s'il s'agit d'un caractère spécial (comme les caractères accentués), hop, on passe à deux octets, trois, voire jusqu'à 6 octets! (selon ce codage :
)
Du coup, tu comprends ce qui t'arrive : au début tu crois lire de l'ASCII, mais en fait c'est de l'UTF8; ça marche bien pour les lettres normales, mais les accents posent problème.
Donc, soit tu utilises l'Unicode sur deux octets tout le temps (UCS-2 ou UTF-16 c'est la même chose), soit tu galères un peu avec des histoires de conversion. PB a heureusement pléthore de nouvelles fonctions pour gérer tout ça selon tes désirs.
PS: merci de me pardonner les approximations! Il y a plein d'autres Unicode, et on pourrait passer des heures sur l'ASCII, le big endian/little endian. C'est pas le but.
Pour faire court, en ASCII, un caractère est codé sur un octet. Pour des raisons historiques, seuls les 7 premiers bits (donc les 128 premiers caractères) sont 'à peu près' sûrs, le reste peut changer d'un pays à l'autre, d'une console à l'autre, etc. Or, les caractères accentués étaient gérés dans ce reste.
Donc, on change tout, il y a maintenant l'Unicode, chouette, on a maintenant (au moins) deux octets par caractère, on va pouvoir avoir 65536 possibilités. Mouaich, sauf que y'en a qui se sont dit que ça prenait de la place, deux octets par caractère! Donc, on a créé l'UTF8 qui encode parfois sur 1 octet (les 7 premiers bits!) et est donc "apparemment" compatible avec l'ASCII; sauf que s'il s'agit d'un caractère spécial (comme les caractères accentués), hop, on passe à deux octets, trois, voire jusqu'à 6 octets! (selon ce codage :

Du coup, tu comprends ce qui t'arrive : au début tu crois lire de l'ASCII, mais en fait c'est de l'UTF8; ça marche bien pour les lettres normales, mais les accents posent problème.
Donc, soit tu utilises l'Unicode sur deux octets tout le temps (UCS-2 ou UTF-16 c'est la même chose), soit tu galères un peu avec des histoires de conversion. PB a heureusement pléthore de nouvelles fonctions pour gérer tout ça selon tes désirs.
PS: merci de me pardonner les approximations! Il y a plein d'autres Unicode, et on pourrait passer des heures sur l'ASCII, le big endian/little endian. C'est pas le but.
-
- Messages : 41
- Inscription : mer. 30/déc./2009 10:11
Re: Lecture de caractères ASCII à partir d'un fichier
Bon, puisque la commande ReadString(fichier_import_id,#PB_UTF8) fonctionne et que la commande ReadString(fichier_import_id,#PB_Unicode) ne fonctionne pas, j'en déduis que le fichier texte généré par excel est un fichier dont les caractères sont codés en UTF-8 et non pas UTF-16.
Est-ce que cette déduction est exacte?
Au vu de tes explications, je comprend que des caractères encodés en UTF-8 peuvent occuper une place de 1 à 6 octets.
C'est le premier octet qui indique le nombre d'octets qu'il faut prendre en compte pour décoder le caractère.
Ainsi, un caractère codé en UTF-8 dont le bit 7 du premier octet vaut 0 sera codé sur un seul octet. Cela peut également être confondu avec un codage Ascii de base (sans accent et autres joyeusetés).
Un caractère codé en UTF-8 dont les bits 7,6 et 5 du premier octet valent respectivement 110 sera codé sur deux octets.
Et ainsi de suite suivant ton tableau. Est-ce exact?
L'encodage UTF-16 encode toujours les caractères sur deux octets. Est-ce exact?
Qu'entent-on exactement par unicode : encodage UTF-8 ou UTF-16 ou les deux?
En tout cas, je traduis les constantes utilisées par purebasic comme ceci:
Sais-tu si les deux OS utilisent l'UTF-8 (ou unicode?) pour encoder les fichiers et si je peux donc utiliser l'encodage UTF-8 sans risquer de problème de compatibilité?
Merci.
Est-ce que cette déduction est exacte?
Au vu de tes explications, je comprend que des caractères encodés en UTF-8 peuvent occuper une place de 1 à 6 octets.
C'est le premier octet qui indique le nombre d'octets qu'il faut prendre en compte pour décoder le caractère.
Ainsi, un caractère codé en UTF-8 dont le bit 7 du premier octet vaut 0 sera codé sur un seul octet. Cela peut également être confondu avec un codage Ascii de base (sans accent et autres joyeusetés).
Un caractère codé en UTF-8 dont les bits 7,6 et 5 du premier octet valent respectivement 110 sera codé sur deux octets.
Et ainsi de suite suivant ton tableau. Est-ce exact?
L'encodage UTF-16 encode toujours les caractères sur deux octets. Est-ce exact?
Qu'entent-on exactement par unicode : encodage UTF-8 ou UTF-16 ou les deux?
En tout cas, je traduis les constantes utilisées par purebasic comme ceci:
- #PB_Ascii : encodage Ascii
#PB_UTF8 : encodage UTF-8
#PB_Unicode : encodage UTF-16 (raison pour laquelle je me demande si unicode est synonyme de UTF-16)
Sais-tu si les deux OS utilisent l'UTF-8 (ou unicode?) pour encoder les fichiers et si je peux donc utiliser l'encodage UTF-8 sans risquer de problème de compatibilité?
Merci.
Re: Lecture de caractères ASCII à partir d'un fichier
Tu as tout compris (c'est rare qu'on me comprenne du premier coup, je vais sabrer le champagne!) 
L'Unicode comprend l'UTF-8, UTF-16 et d'autres (il y a même un UTF-7)...
Pour ce qui est de l'encodage des fichiers, je ne pense pas qu'il y ait de norme relative à l'OS dans son ensemble; chaque programmeur d'application fait ce qu'il veut. L'UTF8 me semble cependant assez répandu. Fred a très bien expliqué tout ça dans la doc sur sa fonction ReadStringFormat().

L'Unicode comprend l'UTF-8, UTF-16 et d'autres (il y a même un UTF-7)...
Pour ce qui est de l'encodage des fichiers, je ne pense pas qu'il y ait de norme relative à l'OS dans son ensemble; chaque programmeur d'application fait ce qu'il veut. L'UTF8 me semble cependant assez répandu. Fred a très bien expliqué tout ça dans la doc sur sa fonction ReadStringFormat().
-
- Messages : 41
- Inscription : mer. 30/déc./2009 10:11
Re: Lecture de caractères ASCII à partir d'un fichier
Bon, je reviens sur l'encodage unicode car je ne comprend pas comment l'utiliser.
J'écris une chaîne de caractères dans un fichier : WriteString(file_id, LSet(prenom,30), #PB_Unicode)
Je veux relire cette chaîne de caractère.
Je ne peux pas utiliser la commande ReadString(file_id , #PB_Unicode) car cette commande lis des caractères jusqu'à ce qu'elle rencontre un retour chariot. Or dans mon cas, les données écrites ne sont pas suivies de retour chariot.
Si j'avais écris la chaîne de caractères à l'aide de la commande WriteString(file_id, LSet(prenom,30), #PB_Ascii), j'aurais pu la relire caractère par caractère (la longueur de la chaîne est connue) dans une boucle à l'aide de la commande ReadAsciiCharacter(file_id)
Par contre, en utilisant la technique de la bloucle, comme j'ai codé la chaîne de caractère en UTF-16, je dois utiliser la commande ReadUnicodeCharacter(file_id). Le problème, c'est que je ne trouve aucune fonction de conversion permettant de convertir le code unicode en caractère affichable que je pourrais concaténer dans une chaîne.
Comment faire pour relire une chaîne de caractères codée en unicode lorsque cette chaîne ne se termine pas par un retour chariot?
Merci.
J'écris une chaîne de caractères dans un fichier : WriteString(file_id, LSet(prenom,30), #PB_Unicode)
Je veux relire cette chaîne de caractère.
Je ne peux pas utiliser la commande ReadString(file_id , #PB_Unicode) car cette commande lis des caractères jusqu'à ce qu'elle rencontre un retour chariot. Or dans mon cas, les données écrites ne sont pas suivies de retour chariot.
Si j'avais écris la chaîne de caractères à l'aide de la commande WriteString(file_id, LSet(prenom,30), #PB_Ascii), j'aurais pu la relire caractère par caractère (la longueur de la chaîne est connue) dans une boucle à l'aide de la commande ReadAsciiCharacter(file_id)
Par contre, en utilisant la technique de la bloucle, comme j'ai codé la chaîne de caractère en UTF-16, je dois utiliser la commande ReadUnicodeCharacter(file_id). Le problème, c'est que je ne trouve aucune fonction de conversion permettant de convertir le code unicode en caractère affichable que je pourrais concaténer dans une chaîne.
Comment faire pour relire une chaîne de caractères codée en unicode lorsque cette chaîne ne se termine pas par un retour chariot?
Merci.
Re: Lecture de caractères ASCII à partir d'un fichier
Tu peux concaténer comme ça (d'ailleurs faudrait que la doc sur chr() soit modifiée)
Code : Tout sélectionner
chaine_unicode.s = "test"
caractere_unicode.u = ReadUnicodeCharacter(file_id)
chaine_unicode + Chr(caractere_unicode)
-
- Messages : 41
- Inscription : mer. 30/déc./2009 10:11
Re: Lecture de caractères ASCII à partir d'un fichier
Merci, ca fonctionne.
J'ai été leurré par la documentation qui indique que le paramètre de Chr est ValeurAscii.
Je n'ai pas pensé a essayer la fonction sur une valeur UTF-16.
J'ai été leurré par la documentation qui indique que le paramètre de Chr est ValeurAscii.
Je n'ai pas pensé a essayer la fonction sur une valeur UTF-16.