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 :

Récupérer des accents dans un fichier par getline


Sujet :

C++

  1. #21
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Citation Envoyé par corrector Voir le message

    Par contre il faudrait que tu indiques le programme complet que tu compiles, avec la ligne de commande exacte utilisée pour compiler.
    Mon programme est actuellement composé de deux fichier .cpp et d'un fichier entête.
    Pour la compilation, je passe par un IDE qui m'a généré un makefile de plus de 600 lignes et j'ai du mal à y retrouver les lignes de compilations. Souhaites-tu que je le colle ici? (ça va faire long).

    Cependant, pour que t'y vois mieux, avant j'étais passé par un makefile fait maison minimaliste qui ressemblait à ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    all:	main
     
    main:	classes.o main.o
    		g++ -g -o main main.o classes.o
     
    classes.o:	classes.cpp classes.h
    		g++ -g -c classes.cpp
     
    main.o:	main.cpp classes.h
    		g++ -g -c main.cpp

  2. #22
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Si ça y est je viens de la trouver:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    .cpp.o:
    	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
    	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
    #	source='$<' object='$@' libtool=no \
    #	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
    #	$(CXXCOMPILE) -c -o $@ $<
    Ce qui décrypté donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    .cpp.o:
    	g++ -DHAVE_CONFIG_H -I. -I$(top_builddir) -I$(srcdir) $(INCLUDES) $(AM_CPPFLAGS) $(AM_CXXFLAGS) -O0 -g3 -MT $@ -MD -MP -MF .deps/$*.Tpo -c -o $@ $<
    	mv -f .deps/$*.Tpo .deps/$*.Po
    J'avoue n'y pas comprendre grand chose.


    Edit: Ah bin je viens de la voire dans les message affichés lors de la compilation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g++ -DHAVE_CONFIG_H -I. -I.. -I/.../.../src -O0 -g3 -MT main.o -MD -MP -MF .deps/bibl.Tpo -c -o main.o main.cpp

  3. #23
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Citation Envoyé par corrector Voir le message
    Mouais :
    é => a9c3c3
    c'est pas de l'UTF-8, c'est sûr.

    ch2[14] => 0
    comme caractère isolé

    Tu appelles locale::global(locale&) avant?
    Au contraire, le code UTF-8 du 'é' est C3A9, donc c'est bien ça.
    En revanche le ch2[14] a effectivement complètement foiré.

    Mal grès mes recherches je n'ai pas avancé d'un pouce aujourd'hui.
    Tu voulais la commande de compilation? Donc tu pense qu'il y a quelque chose à faire de ce coté là. Je ne sais pas ce que tu recherche mais après avoir regardé attentivement le makefile et les options de configuration de Kdevelop (mon IDE) je n'ai trouvé aucune option ou variable semblant avoir un rapport avec l'encodage ou quelque chose comme ça.

    De ce que je pense avoir compris, mal grès le fait qu'il n'est sensé afficher que des chars, mon string arrive a afficher correctement ma chaîne de caractères par ce que tout les octets sont placé les uns à la suites des autres, peut importe leur taille.
    Mais ch2[14] n'y arrive pas parce qu'il vient récupéré qu'un seul et unique octet à la position initiale du 'é'. D'où la répétition du c3 dans la séquence a9c3c3.

    Mais ce qui m'étonne le plus c'est que ni wstring ni wchar_t n'arrivent à afficher des lettres accentuées.

    En fait wchart_t ch1 = 'é' possède bien le bon code décimale contrairement à char ch2 = 'é', mais en sortie il ne l'affiche pas correctement.
    cout << ch1; donne 233
    et
    wcout << ch1; donne deux petits carrés.

  4. #24
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par corrector Voir le message
    Normalement, tu utilises wcin et wcout et c'est bon.
    C'est vrai, à condition d'utiliser des wstring et de compiler avec Visual Studio. Avec g++, ça produit des erreurs de compilation et avec C++ Builder, ça ne fonctionne pas...

    Citation Envoyé par corrector Voir le message
    Ce n'est pas au programmeur de faire ça.
    Si tu veux que ça fonctionne, si. (Ca ne prend que 5 lignes de code pour convertir les n octets d'une lettre UTF-8 en un entier Unicode ... 'é' -> 0xC3E9 en UTF-8 -> 0x009 en Unicode [ISO 10646])
    Si le premier octet de ton code Unicode est 0x00 (il me semble que c'est le cas pour toutes les voyelles accentuées françaises), tu peux même utiliser un seul octet par lettre et utiliser le jeu de caractères ISO-8859-1)

    Personnellement, je jetterais un coup d'oeil à cet article : http://fr.wikipedia.org/wiki/UTF-8 et j'écrirais une petite fonction de conversion pour me retrouver avec toutes les lettres sur 1 octet ( si le texte à traiter est en Français, en Anglais ou Américain )
    Ca permettrait par la suite d'utiliser des string ou char[] et de manipuler les chaînes facilement...
    Tout dépend de ce que tu veux faire avec ton programme...

  5. #25
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par Kaji Voir le message
    C'est vrai, à condition d'utiliser des wstring et de compiler avec Visual Studio. Avec g++, ça produit des erreurs de compilation
    Lesquelles?

    Citation Envoyé par Kaji Voir le message
    et avec C++ Builder, ça ne fonctionne pas...
    C'est à dire?

  6. #26
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par wistiti1234 Voir le message
    Au contraire, le code UTF-8 du 'é' est C3A9, donc c'est bien ça.
    Tu peux la refaire moins vite, j'ai pas pigé la démonstration.

    Si 'é' en UTF-8 donne C3A9, comment a9c3c3 dans le fichier peut correspondre à 'é'?

  7. #27
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par Kaji Voir le message
    Si le premier octet de ton code Unicode est 0x00 (il me semble que c'est le cas pour toutes les voyelles accentuées françaises), tu peux même utiliser un seul octet par lettre et utiliser le jeu de caractères ISO-8859-1)

    Personnellement, je jetterais un coup d'oeil à cet article : http://fr.wikipedia.org/wiki/UTF-8
    Wikipédia est une source d'information parfaitement fiable, c'est bien connu. (Surtout la version française sur l'informatique, voir MTU :
    Citation Envoyé par WP fr
    IPv6 : le MTU par défaut vaut 4352 octets
    Et attention, l'information est "sourcée"!
    Des comme ça, voir pire encore, il y en a à la pelle. Je ferme la parenthèse.)

    Citation Envoyé par Kaji Voir le message
    et j'écrirais une petite fonction de conversion pour me retrouver avec toutes les lettres sur 1 octet ( si le texte à traiter est en Français, en Anglais ou Américain )
    Ca permettrait par la suite d'utiliser des string ou char[] et de manipuler les chaînes facilement...
    Tout dépend de ce que tu veux faire avec ton programme...
    Si j'ai bien compris, tu conseilles de transformer l'UTF-8 en ISO-Latin-1, et de travailler en ISO-Latin-1?

    Tu es au courant que l'ISO-Latin-1 ne permet pas d'écrire le français? (Comme par exemple, ton message auquel je répond!)

  8. #28
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par wistiti1234 Voir le message
    Ok donc 'a' est codé sur 1 octet et 'é' sur 4.
    Non, pas du tout.

  9. #29
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Kaji Voir le message
    C'est vrai, à condition d'utiliser des wstring et de compiler avec Visual Studio. Avec g++, ça produit des erreurs de compilation et avec C++ Builder, ça ne fonctionne pas...
    En fait c'est pas avec g++, mais avec mingw32 que ça compile pas (le portage de g++ pour Windows) ...

    Par exemple :
    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
     
    #include <iostream>
    #include <string>
     
    using namespace std;
     
    int main(int argc, char *argv[]) {  
      wstring strwM = L"test wchar";
      std::wcout << strwM << endl;
      char car;
      wchar_t wcar;  
      cout << "Taille de car = " << sizeof(car) << endl;
      cout << "Taille de wcar = " << sizeof(wcar) << endl;
      //
      cout << "Longueur de la chaine strwM : "
           << strwM.length() << endl;
      for (unsigned int nI = 0; nI < strwM.length(); ++nI) {
        wcar = strwM[nI];     
        wcout << nI << " : " << wcar << endl;
      }  
    	system("PAUSE");
    }// main
    Avec Mingw32 la compilation donne :
    `wcout' is not a member of `std'

    Avec C++ Builder, l'exécution donne :
    Taille de car = 1
    Taille de wcar = 2
    Longueur de la chaine strwM : 10
    Appuyez sur une touche pour continuer...

    Avec Visual Studio Express, l'exécution donne :
    test wchar
    Taille de car = 1
    Taille de wcar = 2
    Longueur de la chaine strwM : 10
    0 : t
    1 : e
    2 : s
    3 : t
    4 :
    5 : w
    6 : c
    7 : h
    8 : a
    9 : r
    Appuyez sur une touche pour continuer...

    En Europe, Windows utilise le WinLatin1 (ou CP1252) qui est un dérivé de l'ISO 8859-1 (on peut utiliser le 8859-15 pour avoir le caractère euro).
    Citation Envoyé par corrector
    Tu es au courant que l'ISO-Latin-1 ne permet pas d'écrire le français ?
    Il te manquerait quel caractère par exemple dans l'ISO 8859-15 pour écrire français ?

    Citation Envoyé par corrector
    Wikipédia est une source d'information parfaitement fiable, c'est bien connu. (Surtout la version française sur l'informatique)
    La source anglaise (http://en.wikipedia.org/wiki/UTF-8) donne les mêmes infos...
    www.utf-8.com fait référence à la doc de wikipédia anglaise... et personnellement j'ai testé leur doc et ça fonctionne...

  10. #30
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par Kaji Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      char car;
      cout << "Taille de car = " << sizeof(car) << endl;
    La masse d'un kg de plomb, ça fait combien en kg?

    Citation Envoyé par Kaji Voir le message
    La source anglaise (http://en.wikipedia.org/wiki/UTF-8) donne les mêmes infos...
    www.utf-8.com fait référence à la doc de wikipédia anglaise... et personnellement j'ai testé leur doc et ça fonctionne...
    Je parle en général. Je ne sais pas si cette page particulière contient des erreurs.

  11. #31
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Citation Envoyé par corrector Voir le message
    Non, pas du tout.
    Effectivement. J'ai fais un sizeof('é') qui m'a renvoyé 4, mais je me rend compte maintenant qu'il y a une tuile quelque part.
    Citation Envoyé par corrector Voir le message
    Tu peux la refaire moins vite, j'ai pas pigé la démonstration.

    Si 'é' en UTF-8 donne C3A9, comment a9c3c3 dans le fichier peut correspondre à 'é'?
    C'est simple, le code utf-8 de 'é' est C3A9 et les octets sont inversé 2 à 2 dans mon fichier.
    Si tu le décode tu lis "el tt er _a cc ne ut é..."

    En réalité il faut lire le fichier comme ceci:
    0000000 6c65 7474 7265 2061 6363 656e 7475 c3a9
    0000010 0ac3 0a00
    0000013
    Et là tu reconnais bien le 'é' de "accentué", suivi d'un fin de ligne, du premier octet de 'é' récupéré par ch2[14] et terminé par un dernier retour à la ligne.

    Citation Envoyé par Kaji Voir le message
    En fait c'est pas avec g++, mais avec mingw32 que ça compile pas (le portage de g++ pour Windows) ...
    Je confirme, g++ arrive très bien à compiler des wstring et wchar_t chez moi.
    Je vais donc passer tout mon programme en wstring puisqu'il semble plus indiqué.
    Mais je n'arrive toujours pas à faire de sortie lisible sur cout/wcout

  12. #32
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Par ailleurs, est-ce que la série des isprint, isalpha, toupper etc... continuent à fonctionner avec les caractères étendus? J'ai un doute en lisant la doc.

  13. #33
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Citation Envoyé par wistiti1234 Voir le message
    Par ailleurs, est-ce que la série des isprint, isalpha, toupper etc... continuent à fonctionner avec les caractères étendus? J'ai un doute en lisant la doc.
    Ah quoique. En faisant un "locale" dans un terminale, je lis "LC_CTYPE=fr_FR.UTF-8".
    Donc peut-être que les commandes ctype sont quand même adapté aux caractères étendu.
    Vous en pensez quoi?

  14. #34
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Ce que je comprends pas c'est que si j'écris:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    wofstream file("test.txt", ios::out);
    wstring ch1 = L"lettre accentué";
    file << ch1 << endl;
    file << ch1[14] << endl;
    file.close();
    Aucun octet n'est écrit dans mon fichier. Alors qu'en string ça marche, même si le ch1[14] foirait.

    Et rajouter un file.imbue(locale("fr_FR.UTF-8")); n'arrange rien.

  15. #35
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Encore une fois, quelle est la longueur de ta chaine?

  16. #36
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Citation Envoyé par corrector Voir le message
    Encore une fois, quelle est la longueur de ta chaine?
    Je sais pas si c'est ce que tu attends, mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    wchar_t c = L'é';
    wstring ch1 = L"lettre accentué";
    cout << ch1.length() << endl;
    cout << sizeof(ch1) << endl;
    cout << sizeof(c) << endl;
    me donne respectivement 15, 4 et 4.

    Si c'est pas ça, explique-moi quelle commande je dois écrire parce que je ne sais pas comment obtenir une longueur autrement.
    Je débute dans ce langage et j'ai encore beaucoup de chose à apprendre.

  17. #37
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par wistiti1234 Voir le message
    Ce que je comprends pas c'est que si j'écris:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    wofstream file("test.txt", ios::out);
    Tu as vérifié que l'ouverture du fichier fonctionne?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (!file) {
        gestion erreur
    }

  18. #38
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Citation Envoyé par corrector Voir le message
    Tu as vérifié que l'ouverture du fichier fonctionne?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (!file) {
        gestion erreur
    }
    Oui. Pas avec ton test, mais en faisant une sortie texte standard, type file << "blabla"; qui lui s'inscrivait sans problème.

  19. #39
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Je comprend plus rien. Maintenant la sortie vers un fichier de caractères étendu fonctionne!
    Le code suivant marche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    wofstream file("test.txt", ios::out);
    file.imbue(locale("fr_FR.UTF-8"));
    wstring ch1 = L"lettre accentué";
    file << ch1 << endl;
    file << ch1[14] << endl;
    file.close();
    Par contre si j'enlève le imbue, là plus aucun octet ne sort.
    Pourtant j'avais essayé ce code hier et ça ne donnait rien

    Par contre l'affichage vers la sortie standard ne marche toujours pas.
    Et cout.imbue(locale("fr_FR.UTF-8")); ou wcout.imbue(locale("fr_FR.UTF-8"));
    N'arrangent rien cette fois-ci. (Du moins pour le moment. Je disais aussi ça pour le premier cas)

    En fait c'est même plus bizarre que ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	wstring ch1 = L"léàçi";
    	cout << "léàçi:" << endl;
    	wcout << ch1 << endl;
    	cout << "léàçi" << endl;
    Donne:
    léàçi
    l���i
    (avec 6 petits carrés entre le 'l' et le 'i')
    léàçi

    Et:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	wstring ch1 = L"léàçi";
    	//cout << "léàçi:" << endl;
    	wcout << ch1 << endl;
    	cout << "léàçi" << endl;
    Donne:
    l???i
    Les carrés sont remplacé par des points d'interrogations et la dernières instruction n'est pas du tout traité!

    Je l'ai constaté plusieurs fois durant mes tests. J'obtiens des points d'interrogations à chaque fois que je sort du texte normalement avant, sinon c'est les petits carrés.


    Edit: Je viens de vérifier avec la commande int i=ch1[1], dans les deux cas i vaut 233 (code du 'é').

  20. #40
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par wistiti1234 Voir le message
    Effectivement. J'ai fais un sizeof('é') qui m'a renvoyé 4, mais je me rend compte maintenant qu'il y a une tuile quelque part.
    sizeof(char) = 1 par définition.

    Tu peux vérifier que le type de 'é' est int :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::cout << "é : int " << std::boolalpha << typeid('é') == typeid(int) 
              << "\n'é' = " << std::hex << 'é' << std::end;
    Citation Envoyé par wistiti1234 Voir le message
    C'est simple, le code utf-8 de 'é' est C3A9 et les octets sont inversé 2 à 2 dans mon fichier.
    Si tu le décode tu lis "el tt er _a cc ne ut é..."
    Mince alors. J'ai l'habitude de lire les octets dans l'ordre.

    Là ça colle!

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Réponses: 10
    Dernier message: 23/04/2007, 14h18
  2. Réponses: 1
    Dernier message: 05/09/2006, 17h56
  3. récupérer des données dans un fichier
    Par pymouse dans le forum Langage
    Réponses: 7
    Dernier message: 19/06/2006, 17h43
  4. Réponses: 2
    Dernier message: 16/01/2006, 19h34
  5. Réponses: 1
    Dernier message: 22/12/2005, 15h45

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