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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    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
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    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 Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Es-tu sous Linux ???
    Citation Envoyé par orphean Voir le message

  4. #4
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    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
    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
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    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
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    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
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    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

  9. #9
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 45
    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

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    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

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    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

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    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.

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. 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