IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

lLecture de fichiers comportant des caractères cyrilliques et latins


Sujet :

C

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    Points : 29
    Points
    29
    Par défaut lLecture de fichiers comportant des caractères cyrilliques et latins
    Bonjour,

    Je n'arrive à rien, je ne m'en sors pas.
    Je veux lire un fichier de données littérales, et faire un traitement sur le premier mot de chaque ligne balisé par des caractères spéciaux.

    Voici deux lignes de mon fichier:

    =◄абз:а:ц►, -а, тв. -ем, р. мн. -ев║
    =◄абрик:о:с►, -а, р. мн. -ов║

    Voici mon programme (j'ai tellement merdé, que j'ai presque tout effacé, et gardé le minimum: la lecture de la 1e ligne seulement):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(int argc, char *argv[])
    {
      #define TEMP_FILE "test.txt"
      int i;
      lecture(TEMP_FILE);
      system("PAUSE");
      return 0;
    }
     
     
    int lecture (char const * const s_filename)
    {
       FILE * p_file_src    = NULL;
       char * s_line        = NULL;
     
       if (!s_filename) return 0;
       /* ----- Ouverture fichier ----- */
       p_file_src = fopen (s_filename, "r");
       if (!p_file_src) return 0;
       /* ----- Allocation d'un tableau pour contenir la 1e ligne ----- */
       printf("%d\n", BUFSIZ);
       s_line = malloc (BUFSIZ);
       if (!s_line)
       {
          fclose (p_file_src);
          return 0;
       }
       /* ----- Lecture 1e ligne du fichier ----- */
       fgets (s_line, BUFSIZ, p_file_src);
       /* ----- affichage de cette ligne, plus tard, traitement ----- */
       printf(">>>%s<<<\n", s_line);
       /* ----- Fermeture du fichier ----- */
       /* Fermeture du fichier. */
       fclose (p_file_src);
       /* Liberation de la memoire. */
       free (s_line);
       s_line = NULL;
       return 1;
    }
    Le résultat:
    512
    >>> =<<<
    Et là, j'ai plus arrêté de croire que je pourrais y arriver seul... J'ai quand même essayé une dernière chose: j'ai eu l'idée de changer mon fichier de données en:
    =<cheval>, -aux║
    =<chou>, -x║
    Et ça donne la même chose! J'ai conclu que ce n'était pas les caractères cyrilliques qui posaient problème, et j'ai résolu de demander de l'aide...

    L'idéal, pour moi, c'est de sortir pour chaque ligne lue, trois variables:
    - var_entree, chaîne de caractères contenant tous les caractères entre '=' et '║'
    - var_mot, chaîne de caractères contenant tous les caractères entre '<' et '>'
    - var_flexion, chaîne de caractères commençant par le 1er '-' après '>, ' et allant jusqu'à '║'

    Je ferai mon traitement et je copierai var_mot_traitee et var_flexion_traitee à la suite de var_entree dans un nouveau fichier.

    Je croyais que ce serait un jeu d'enfant, grande désillusion! Je n'ai même pas dépassé le stade de lecture de la 1e ligne...

    Vous pouvez m'aider?

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Es-tu sous Linux ??? Si oui vérifie avec la commande "locale" si t'es en UTF8.
    Si c'est le cas, alors tout caractère spécial est traduit en UTF8 par 2 caractères. Pour vérifier ce fait, tu tapes echo "ééé" >toto et tu verras que toto fait 7 caractères (au lieu de 3).

    Voici pour l'environnement. J'attends ta réponse pour la suite. Sinon ton code me semble correct à première vue mais je l'ai pas testé. Juste un détail => si BUFSIZ est une valeur numérique, tu peux alors éviter le malloc/free en déclarant un tableau de char[BUFSIZ].
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Es-tu sous Linux ???
    Citation Envoyé par orphean Voir le message
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  4. #4
    Nouveau membre du Club
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    Points : 29
    Points
    29
    Par défaut
    Je suis sous windows.
    J'utilise dev-C++ 4.9.9.2

    Merci pour ton avis sur mon code. Au moins, c'est toujours ça de réconfortant pour moi. Ma difficulté, c'est peut-être effectivement une histoire de codage de caractères. J'ai déjà lu des choses concernant UTF8, mais je n'y connais rien. Car en réalité, je n'y ai été jamais confronté de près. Je pense qu'ici, c'est là le manque...

    En fait, dès que j'arriverai à lire correctement les caractères cyrilliques, à les afficher correctement à l'écran pour vérifier, à les comparer avec des caractères cyrilliques que j'aurai tapés directement dans mon code, tout sera bon. Je pense...

    A tout hasard, ce n'est peut-être pas nécessaire que je le dise, mais au cas où, sans rentrer trop dans le détail, je fais essayer d'expliquer pourquoi je fais ça.

    Je veux une petite application qui puisse écrire des mots russes en phonologie. L'algorithme un petit peu élaboré. C'est pour ça que j'ai essayé en C. Sans rentrer trop dans le détail, je fais essayer de donner un aperçu de la rigueur phonologique.

    - Je prends l'exemple de la lettre <е> russe, c'est une voyelle dite molle (souvent prononcé "yé", la voyelle dure correspondante est <э>, souvent prononcée "è").
    - Il me semble nécessaire d'expliquer ici que la plupart des consonnes russes vont par couple, une dure, une molle. Ainsi <не> s'écrit en phonologie /n'e/ et <нэ> s'écrirait /ne/. Dans le 1e cas, /n/ est mou, c'est ce qu'indique l'apostrophe dans /n'e/, dans le 2e cas, /n/ est dur (par défaut, pas d'indication /ne/). Autrement dit, l'orthographe et la phonologie n'ont pas la même transcription. En phonologie, c'est la consonne (de couple) qui est dure ou molle, alors qu'en orthographe, c'est la voyelle. Donc en orthographe, il y en a 10 voyelles, 5 dures, 5 molles, alors qu'en phonologie, il n'y a que 5 voyelles.
    - Quand la même lettre russe <е> commence un mot, elle cache un yod (en français son 'ill' comme paille, mais aussi 'ï' dans aïe, et 'il' dans rail, et aussi 'y' dans noyer; en espagnol 'll' dans paella, en italien 'gl' dans Vintimigla, en portugais 'lh' dans coelho). Dons en début de mot, <ен...> s'écrirait /jen.../.
    - De plus, en russe il existe un signe mou et un signe dur pour séparer une consonne de la voyelle qui suit, si cette voyelle contient un yod.
    <объектив> s'écrit /ob"jekt'iv/
    <коллье> s'écrit /koll'je/
    - Pour finir très vite, certaines consonnes sont toujours dures, d'autres toujours molles, d'autres encore toujours dures avec certaines voyelles et toujours molles avec les autres. Dans ce cas, inutile de rajouter l'apostrophe.

    Pardon si c'est trop long. Tout la fin n'est pas importante. Mais j'essaie de donner le maximum d'information pour que tu puisses m'aider.

    Et déjà grand merci!

  5. #5
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Points : 403
    Points
    403
    Par défaut
    Salut,

    Je ne comprends pas bien. Comment on sort les lettres russes au clavier avec une page de code français ?

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par orphean Voir le message
    Je suis sous windows.
    J'utilise dev-C++ 4.9.9.2

    Merci pour ton avis sur mon code. Au moins, c'est toujours ça de réconfortant pour moi. Ma difficulté, c'est peut-être effectivement une histoire de codage de caractères. J'ai déjà lu des choses concernant UTF8, mais je n'y connais rien. Car en réalité, je n'y ai été jamais confronté de près. Je pense qu'ici, c'est là le manque...

    En fait, dès que j'arriverai à lire correctement les caractères cyrilliques, à les afficher correctement à l'écran pour vérifier, à les comparer avec des caractères cyrilliques que j'aurai tapés directement dans mon code, tout sera bon. Je pense...

    A tout hasard, ce n'est peut-être pas nécessaire que je le dise, mais au cas où, sans rentrer trop dans le détail, je fais essayer d'expliquer pourquoi je fais ça.

    Je veux une petite application qui puisse écrire des mots russes en phonologie. L'algorithme un petit peu élaboré. C'est pour ça que j'ai essayé en C. Sans rentrer trop dans le détail, je fais essayer de donner un aperçu de la rigueur phonologique.

    - Je prends l'exemple de la lettre <е> russe, c'est une voyelle dite molle (souvent prononcé "yé", la voyelle dure correspondante est <э>, souvent prononcée "è").
    - Il me semble nécessaire d'expliquer ici que la plupart des consonnes russes vont par couple, une dure, une molle. Ainsi <не> s'écrit en phonologie /n'e/ et <нэ> s'écrirait /ne/. Dans le 1e cas, /n/ est mou, c'est ce qu'indique l'apostrophe dans /n'e/, dans le 2e cas, /n/ est dur (par défaut, pas d'indication /ne/). Autrement dit, l'orthographe et la phonologie n'ont pas la même transcription. En phonologie, c'est la consonne (de couple) qui est dure ou molle, alors qu'en orthographe, c'est la voyelle. Donc en orthographe, il y en a 10 voyelles, 5 dures, 5 molles, alors qu'en phonologie, il n'y a que 5 voyelles.
    - Quand la même lettre russe <е> commence un mot, elle cache un yod (en français son 'ill' comme paille, mais aussi 'ï' dans aïe, et 'il' dans rail, et aussi 'y' dans noyer; en espagnol 'll' dans paella, en italien 'gl' dans Vintimigla, en portugais 'lh' dans coelho). Dons en début de mot, <ен...> s'écrirait /jen.../.
    - De plus, en russe il existe un signe mou et un signe dur pour séparer une consonne de la voyelle qui suit, si cette voyelle contient un yod.
    <объектив> s'écrit /ob"jekt'iv/
    <коллье> s'écrit /koll'je/
    - Pour finir très vite, certaines consonnes sont toujours dures, d'autres toujours molles, d'autres encore toujours dures avec certaines voyelles et toujours molles avec les autres. Dans ce cas, inutile de rajouter l'apostrophe.

    Pardon si c'est trop long. Tout la fin n'est pas importante. Mais j'essaie de donner le maximum d'information pour que tu puisses m'aider.

    Et déjà grand merci!
    Et pourquoi le faire en C ? Pourquoi ne pas utiliser un langage plus souple et plus évolué comme par exemple Python ??? Bon je veux pas non plus paraitre inquisiteur mais je connais Python aussi et je sais qu'il est très performant et offre en parallèle des outils assez évolués...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Nouveau membre du Club
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    Points : 29
    Points
    29
    Par défaut
    Je réponds d'abord à vos deux questions.

    Pourquoi le C plutôt qu'un autre langage?

    Parce que je connais le C (j'ai programmé il y a 10 ans environ 10 000 lignes de code pendant 2 ans).
    Au début, j'ai posté un appel à l'aide sur un forum qui n'était pas le bon. Un modérateur m'a parlé alors de Perl (avant de déplacer la discussion).
    Maintenant, tu me parles de Python.
    En fait, j'étudie le russe pour mon plaisir, et je pense que je n'aurai pas le temps (peut-être pas le courage non plus) d'apprendre un autre langage. Même si je ne doute pas que comme toute chose, et comme les langues, il suffit d'un peu de pratique quotidienne por venir à bout d'un nouveau langage.

    Comment écrit-on des caractères cyrilliques dans un fichier code en C?

    C'est toute ma question.
    Pour l'instant, j'essaie seulement de créer du code en C qui puisse lire un fichier contenant des caractères cyrilliques. Pour cela, j'ai créé un fichier .txt enregistré dans le format unicode.

    Je pose maintenant une question.

    Est-ce que la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgets (s_line, BUFSIZ, p_file_src);
    permet de lire normalement des caractères unicode?

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par orphean Voir le message
    Je pose maintenant une question.

    Est-ce que la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgets (s_line, BUFSIZ, p_file_src);
    permet de lire normalement des caractères unicode?
    Je peux pas te répondre avec certitudes. Je serais tenté de dire que oui, la fonction utilise le format du fichier.

    Sinon le gars t'as parlé de Perl, moi de Python. Comme quoi les idées se rejoignent car Python est né du Perl...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    À moins d'être sur un système entièrement en UTF-8 (comme certains Linux), fgets() ne permet pas de lire de l'unicode.
    Ni même fgetws(), car il n'y a rien en C standard pour dire "ce fichier contient des caractères larges". Si tu fais une lecture normale, les fonctions standard liront caractère "mince" par caractère "mince" et convertiront en caractères larges ensuite.

    Les versions récentes des bibliothèques C de Microsoft proposent des extensions pour contourner ce problème, mais si tu n'as pas un Visual récent (ou si tu veux être portable), il te faudra utiliser une bibliothèque extérieure ou bien lire le fichier en mode binaire et faire toutes les conversions par toi-même.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Nouveau membre du Club
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    Points : 29
    Points
    29
    Par défaut
    il te faudra [...] lire le fichier en mode binaire et faire toutes les conversions par toi-même.
    Super, j'ai compris le principe, donc ça me paraît accessible. En tout cas, je suis prêt à m'y essayer. (De toute façon, je n'ai pas linux, et je ne m'y mettrai pas avant d'avoir réussi ce que je veux faire dans l'immédiat.)

    Question: une piste pour me renseigner sur les façons de lire en binaire, et de faire les conversions moi-même? Sur les noms des fonctions à utiliser pour le faire? Pour effectuer des tests de comparaisons?

    Par exemple, j'ai commencé à me renseigner, et j'ai rassemblé les infos suivantes (par ordre de colonne: Caractères, Numéros de caractères en hex, Unités de code UTF-8, Unités de code UTF-16, Appels de caractère numériques hex, Appels de caractère numériques décimaux)
    J'ignore si ça a rapport avec les conversions dont tu parles, mais peut-être sauras-tu me le dire?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    а	  /  430  /	/  D0 B0  /	/  0430  /	/  &#x430  /	/  &# 1072  /
    б	  /  431  /	/  D0 B1  /	/  0431  /	/  &#x431  /	/  &# 1073  /
    в	  /  432  /	/  D0 B2  /	/  0432  /	/  &#x432  /	/  &# 1074  /
    г	  /  433  /	/  D0 B3  /	/  0433  /	/  &#x433  /	/  &# 1075  /
    д	  /  434  /	/  D0 B4  /	/  0434  /	/  &#x434  /	/  &# 1076  /
    е	  /  435  /	/  D0 B5  /	/  0435  /	/  &#x435  /	/  &# 1077  /
    ё	  /  451  /	/  D1 91  /	/  0451  /	/  &#x451  /	/  &# 1105  /
    ж	  /  436  /	/  D0 B6  /	/  0436  /	/  &#x436  /	/  &# 1078  /
    з	  /  437  /	/  D0 B7  /	/  0437  /	/  &#x437  /	/  &# 1079  /
    и	  /  438  /	/  D0 B8  /	/  0438  /	/  &#x438  /	/  &# 1080  /
    й	  /  439  /	/  D0 B9  /	/  0439  /	/  &#x439  /	/  &# 1081  /
    к	  /  43A  /	/  D0 BA  /	/  043A  /	/  &#x43A  /	/  &# 1082  /
    л	  /  43B  /	/  D0 BB  /	/  043B  /	/  &#x43B  /	/  &# 1083  /
    м	  /  43C  /	/  D0 BC  /	/  043C  /	/  &#x43C  /	/  &# 1084  /
    н	  /  43D  /	/  D0 BD  /	/  043D  /	/  &#x43D  /	/  &# 1085  /
    о	  /  43E  /	/  D0 BE  /	/  043E  /	/  &#x43E  /	/  &# 1086  /
    п	  /  43F  /	/  D0 BF  /	/  043F  /	/  &#x43F  /	/  &# 1087  /
    р	  /  440  /	/  D1 80  /	/  0440  /	/  &#x440  /	/  &# 1088  /
    с	  /  441  /	/  D1 81  /	/  0441  /	/  &#x441  /	/  &# 1089  /
    т	  /  442  /	/  D1 82  /	/  0442  /	/  &#x442  /	/  &# 1090  /
    у	  /  443  /	/  D1 83  /	/  0443  /	/  &#x443  /	/  &# 1091  /
    ф	  /  444  /	/  D1 84  /	/  0444  /	/  &#x444  /	/  &# 1092  /
    х	  /  445  /	/  D1 85  /	/  0445  /	/  &#x445  /	/  &# 1093  /
    ц	  /  446  /	/  D1 86  /	/  0446  /	/  &#x446  /	/  &# 1094  /
    ч	  /  447  /	/  D1 87  /	/  0447  /	/  &#x447  /	/  &# 1095  /
    ш	  /  448  /	/  D1 88  /	/  0448  /	/  &#x448  /	/  &# 1096  /
    щ	  /  449  /	/  D1 89  /	/  0449  /	/  &#x449  /	/  &# 1097  /
    ъ	  /  44A  /	/  D1 8A  /	/  044A  /	/  &#x44A  /	/  &# 1098  /
    ы	  /  44B  /	/  D1 8B  /	/  044B  /	/  &#x44B  /	/  &# 1099  /
    ь	  /  44C  /	/  D1 8C  /	/  044C  /	/  &#x44C  /	/  &# 1100  /
    э	  /  44D  /	/  D1 8D  /	/  044D  /	/  &#x44D  /	/  &# 1101  /
    ю	  /  44E  /	/  D1 8E  /	/  044E  /	/  &#x44E  /	/  &# 1102  /
    я	  /  44F  /	/  D1 8F  /	/  044F  /	/  &#x44F  /	/  &# 1103  /
    А	  /  410  /	/  D0 90  /	/  0410  /	/  &#x410  /	/  &# 1040  /
    Б	  /  411  /	/  D0 91  /	/  0411  /	/  &#x411  /	/  &# 1041  /
    В	  /  412  /	/  D0 92  /	/  0412  /	/  &#x412  /	/  &# 1042  /
    Г	  /  413  /	/  D0 93  /	/  0413  /	/  &#x413  /	/  &# 1043  /
    Д	  /  414  /	/  D0 94  /	/  0414  /	/  &#x414  /	/  &# 1044  /
    Е	  /  415  /	/  D0 95  /	/  0415  /	/  &#x415  /	/  &# 1045  /
    Ё	  /  401  /	/  D0 81  /	/  0401  /	/  &#x401  /	/  &# 1025  /
    Ж	  /  416  /	/  D0 96  /	/  0416  /	/  &#x416  /	/  &# 1046  /
    З	  /  417  /	/  D0 97  /	/  0417  /	/  &#x417  /	/  &# 1047  /
    И	  /  418  /	/  D0 98  /	/  0418  /	/  &#x418  /	/  &# 1048  /
    Й	  /  419  /	/  D0 99  /	/  0419  /	/  &#x419  /	/  &# 1049  /
    К	  /  41A  /	/  D0 9A  /	/  041A  /	/  &#x41A  /	/  &# 1050  /
    Л	  /  41B  /	/  D0 9B  /	/  041B  /	/  &#x41B  /	/  &# 1051  /
    М	  /  41C  /	/  D0 9C  /	/  041C  /	/  &#x41C  /	/  &# 1052  /
    Н	  /  41D  /	/  D0 9D  /	/  041D  /	/  &#x41D  /	/  &# 1053  /
    О	  /  41E  /	/  D0 9E  /	/  041E  /	/  &#x41E  /	/  &# 1054  /
    П	  /  41F  /	/  D0 9F  /	/  041F  /	/  &#x41F  /	/  &# 1055  /
    Р	  /  420  /	/  D0 A0  /	/  0420  /	/  &#x420  /	/  &# 1056  /
    С	  /  421  /	/  D0 A1  /	/  0421  /	/  &#x421  /	/  &# 1057  /
    Т	  /  422  /	/  D0 A2  /	/  0422  /	/  &#x422  /	/  &# 1058  /
    У	  /  423  /	/  D0 A3  /	/  0423  /	/  &#x423  /	/  &# 1059  /
    Ф	  /  424  /	/  D0 A4  /	/  0424  /	/  &#x424  /	/  &# 1060  /
    Х	  /  425  /	/  D0 A5  /	/  0425  /	/  &#x425  /	/  &# 1061  /
    Ц	  /  426  /	/  D0 A6  /	/  0426  /	/  &#x426  /	/  &# 1062  /
    Ч	  /  427  /	/  D0 A7  /	/  0427  /	/  &#x427  /	/  &# 1063  /
    Ш	  /  428  /	/  D0 A8  /	/  0428  /	/  &#x428  /	/  &# 1064  /
    Щ	  /  429  /	/  D0 A9  /	/  0429  /	/  &#x429  /	/  &# 1065  /
    Ъ	  /  42A  /	/  D0 AA  /	/  042A  /	/  &#x42A  /	/  &# 1066  /
    Ы	  /  42B  /	/  D0 AB  /	/  042B  /	/  &#x42B  /	/  &# 1067  /
    Ь	  /  42C  /	/  D0 AC  /	/  042C  /	/  &#x42C  /	/  &# 1068  /
    Э	  /  42D  /	/  D0 AD  /	/  042D  /	/  &#x42D  /	/  &# 1069  /
    Ю	  /  42E  /	/  D0 AE  /	/  042E  /	/  &#x42E  /	/  &# 1070  /
    Я	  /  42F  /	/  D0 AF  /	/  042F  /	/  &#x42F  /	/  &# 1071  /

  11. #11
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    [réponse publique à un courrier privé]
    Citation Envoyé par orphean Voir le message
    La seule chose à savoir, je pense, c'est que je n'arrive pas à lire, affecter, afficher correctement des chaînes de caractères qui sont dans un fichier.

    Pour réduire ma question, imaginons un fichier qui contient plusieurs lignes du type:

    =◄абз:а:ц►, -а, тв. -ем, р. мн. -ев║
    =◄абрик:о:с►, -а, р. мн. -ов║
    =◄Росс:и:я►, -и║
    =◄Аз:о:вское м:о:ре►, -я║
    =◄США►║
    =◄:А:зия►, -и║
    =◄Алж:и:р►, -а║
    Je vois des caractères bizarres et des caractères cyriliques... Ce qu'il faut savoir, c'est que le langage C ne connait en standard qu'un jeu de caractères réduit :

    http://delahaye.emmanuel.free.fr/spip.php?article6

    Néanmoins, depuis 1995, il supporte le type 'wchar_t' qui implémente les caractères dits 'larges', tels que ceux qui sont utilisés par unicode, système de codage de caractères très large couvrant tous les caractères de la terre et même au-delà (il y a une plage de code pour le Klingon !).

    Si ton fichier utilise de tels caractères, il faut utiliser tout l'arsenal des fonctions 'w' basées sur le type wchar_t. Détails ici :

    http://www.opengroup.org/onlinepubs/...h/wchar.h.html
    Pas de Wi-Fi à la maison : CPL

  12. #12
    Nouveau membre du Club
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    Points : 29
    Points
    29
    Par défaut Ca ne marche toujours pas...
    Voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <wchar.h>
     
    int main(void)
    {
       FILE    *stream;
       wchar_t  wcs[100];
       int      compt;
       int      *lect_ligne;
     
       if (NULL == (stream = fopen("fgetws.txt", "r"))) {
          system("PAUSE");
          printf("Unable to open: \"fgetws.txt\"\n");
          exit(1);
       }
     
       compt = 0;
       errno = 0;
       while (1) {
          lect_ligne = fgetws(wcs, 100, stream);
          compt ++;
          if (NULL == lect_ligne) {
             if (EILSEQ == errno) {
                printf("An invalid wide character was encountered.\n");
                system("PAUSE");
                exit(1);
             }
             else if (feof(stream)) {
                     printf("End of file reached.\n");
                     system("PAUSE");
                     exit(1);
                     }
                  else {
                     perror("Read error.\n");
                     }
          }
          printf("compt = %d\n", compt);
          printf("wcs = \"%ls\"\n", wcs);
          system("PAUSE");
       }
       fclose(stream);
       return 0;
    }
    Si quelqu'un peut tester ce code avec le fichier joint, et me donner son avis, ce serait super!

    Je ne décolle toujours pas...
    Fichiers attachés Fichiers attachés

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par orphean Voir le message
    Voici mon code:
    <...>Si quelqu'un peut tester ce code avec le fichier joint, et me donner son avis, ce serait super!
    Tu peux déjà corriger ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    Project   : Orphean
    Compiler  : GNU GCC Compiler (called directly)
    Directory : D:\dev\orphean\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: main3.c
    main3.c: In function `main':
    main3.c:22: warning: assignment from incompatible pointer type
    main3.c:43: warning: will never be executed
    main3.c:43: warning: will never be executed
    main3.c:43: warning: will never be executed
    Linking console executable: D:\dev\orphean\console.exe
    Process terminated with status 0 (0 minutes, 6 seconds)
    0 errors, 4 warnings
    Pas de Wi-Fi à la maison : CPL

  14. #14
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    ton fichier fwgets.txt présente un BOM (Byte-Order Mark) FFFE qui indique que le contenu est encodé en UTF16.

    Donc, tu dois déjà skipper ce BOM (codé sur 2 bytes)

    De plus tu ouvres ton fichier en mode texte, ce qui implique une conversion des données -> ansi.

    Si tu l'ouvre en binaire par "rb", il n'y a pas de conversion -> ansi.

    J'ai pris ton code :
    • modifié le mode de fopen de "r" en "rb"
    • ajouté le skip du BOM par 2 fgetwc(stream) (pour faire vite)
    Et enfin la, la lecture est correcte !

    (du moins dans le débugger car dans la console c'est pas jojo - sous MS la console ne comprend pas les caractères unicode..)
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Citation Envoyé par vicenzo Voir le message
    sous MS la console ne comprend pas les caractères unicode..)
    Ça dépend de la version: Sous 2005, ça marche.
    Malheureusement, MinGW utilise MSVCRT.DLL, la C Run-Time Library de Visual C++ 6, qui ne supporte pas les caractères unicode (putws() foire, par contre la fonction Win32 WriteConsoleW() marche).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Nouveau membre du Club
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    Points : 29
    Points
    29
    Par défaut Progrès... mais c'est pas encore ça!
    J'ai corrigé les faiblesses soulevées par GNU GCC (merci Emmanuel).
    J'ai compris le coup du BOM et le "rb" (merci Vicenzo).
    Je confirme que l'affichage MS est lacunaire: pire, il est inexistant... (pardon Médinoc, mais je suis dépassé par tes indications).

    Bref, pour essayer de faire du clair dans mes manips et vérifier le contenu de mes chaînes de caractères, j'ai amélioré le programme en recopiant dans un fichier en sortie ce qui est lu du premier. Le résultat skippe tous les caractères cyrilliques...

    Que pensez-vous du résultat (fichiers joints, fichier en sortie="..._out.txt")?

    J'ai une autre question. D'après mes informations, la première lettre de l'alphabet cyrillique majuscule (équivalent du 'A' latin) correspond à "&#x430" en "appel de caractère numériques décimaux". Pouvez-vous me donner un exemple élémentaire d'usage d'affectation de cette valeur codée en dur "&#x430" à une variable wchar_t, avec emploi de fprintf qui la copie dans un fichier (pour vérifier ce qui est écrit dans le fichier)?
    Fichiers attachés Fichiers attachés

  17. #17
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Bon, pour avoir un fichier fgetws_out.txt identique au fichier d'entrée, tu dois faire deux choses :
    • ajouter le BOM
    • écrire correctement tes chaines larges dans le fichier de sortie
    Donc, pour le bom, remplace :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fgetwc(stream); /* pour skipper le BOM (Byte-Order Mark) FFFE */
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    wchar_t bom:
     
    /* .... */
     
    bom = fgetwc(stream); /* pour skipper le BOM (Byte-Order Mark) FFFE */
    fwrite(&bom, sizeof(bom), 1, stream_out); /*écriture du BOM dans le fichier de sortie */
    Et ensuite pour faire l'output correct, remplace :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fprintf(stream_out, "%ls", wcs);
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fwrite(wcs, wcslen(wcs)*sizeof(wchar_t), 1, stream_out);
    Ces deux modifs te génèreront un ouput identique à l'input...
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  18. #18
    Nouveau membre du Club
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    Points : 29
    Points
    29
    Par défaut Merci! Merci! Merci!
    Merci mille fois, Vicenzo! C'était totalement hors de ma portée... Maintenant, je commence à m'y retrouver. Et j'ai utilisé ta soluce en fwrite pour afficher à l'écran avec MS:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fwrite(wcs, wcslen(wcs)*sizeof(wchar_t), 1, stdout);
    Même si chaque caractère unicode est affiché sur MS avec deux caractères imprimables dos, en les observant bien, je peux les distinguer!

    Par contre, je ne comprends pas pourquoi
    1) sur l'invite msdos, pour les 6 premières lignes qui contiennent des caractères latins et cyrilliques uniquement, la première lettre ne s'affiche pas,
    2) de même pour la première ligne
    =◄аар:о:новец►, -вца, тв. -вцем║
    (par comparaison avec les suivantes qui commencent par les 2 mêmes caractères '=◄', seul le deuxième '◄' est affiché, il manque le '=')
    3) les lignes suivantes s'affichent correctement, avec en premier le '='

    C'est comme s'il la lecture des premières lignes englobaient et 'perdaient' le 1er caractère de la suivante, ce qui semble se terminer dès que la ligne lue se termine par '║'...

    Si tu as une explication, je suis preneur, sinon, pas grave, dans mon esprit, ça restera imputable aux miracles MS...


    J'ai une autre question: comment connaître le code &#x--- d'un caractère cyrillique unicode et comment affecter &#x517 (au hasard) à un caractère large?
    Connaître le code "&#x---"?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    wcs="=◄аар:о:новец►, -вца, тв. -вцем║"; /* pas sûr que la syntaxe soit bonne */
    car=wcs[2];
    printf("?????", car); /* c'est la bonne syntaxe que je cherche */
    Affecter un "&#x---" à un caractère large?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    car="&#x517"; /* c'est la bonne syntaxe que je cherche */
    Mille... et (encore) une fois merci!

  19. #19
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    et comment affecter &#x517 (au hasard) à un caractère large?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
      6.4.3 Universal character names
      Syntax
    1          universal-character-name:
                       \u hex-quad
                       \U hex-quad hex-quad
               hex-quad:
                       hexadecimal-digit hexadecimal-digit
                                          hexadecimal-digit hexadecimal-digit
      Constraints
    2 A universal character name shall not specify a character whose short identifier is less than
      00A0 other than 0024 ($), 0040 (@), or 0060 (), nor one in the range D800 through
      DFFF inclusive.62)
      Description
    3 Universal character names may be used in identifiers, character constants, and string
      literals to designate characters that are not in the basic character set.
      Semantics
    4 The universal character name \Unnnnnnnn designates the character whose eight-digit
      short identifier (as specified by ISO/IEC 10646) is nnnnnnnn.63) Similarly, the universal
      character name \unnnn designates the character whose four-digit short identifier is nnnn
      (and whose eight-digit short identifier is 0000nnnn).
     
     
      62) The disallowed characters are the characters in the basic character set and the code positions reserved
           by ISO/IEC 10646 for control characters, the character DELETE, and the S-zone (reserved for use by
           UTF−16).
      63) Short identifiers for characters were first specified in ISO/IEC 106461/AMD9:1997.
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  20. #20
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par orphean Voir le message
    D'après mes informations, la première lettre de l'alphabet cyrillique majuscule (équivalent du 'A' latin) correspond à "&#x430" en "appel de caractère numériques décimaux". Pouvez-vous me donner un exemple élémentaire d'usage d'affectation de cette valeur codée en dur "&#x430" à une variable wchar_t,
    avec emploi de fprintf qui la copie dans un fichier (pour vérifier ce qui est écrit dans le fichier)?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fwprintf (fp, L"%c", c);
    ou
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. Fichier contenant des caractères cyrilliques
    Par DSGSLA dans le forum Windows
    Réponses: 1
    Dernier message: 06/08/2010, 14h49
  2. Positionner/écrire dans un fichier texte des caractères là où on veut
    Par nicofromChina dans le forum Entrée/Sortie
    Réponses: 11
    Dernier message: 01/04/2009, 15h42
  3. Réponses: 2
    Dernier message: 16/11/2008, 16h09
  4. [Oracle] Insertion de données comportant des caractères accentués
    Par elzebore dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 28/11/2007, 19h44
  5. Réponses: 5
    Dernier message: 07/10/2007, 17h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo