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. #41
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 118
    Points : 176
    Points
    176
    Par défaut
    Citation Envoyé par corrector Voir le message
    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;
    Voilà l'explication de mon sizeof('é') = 4!
    Effectivement, 'é' est un int, et un int vaut 4 octets chez moi. (ça dépend des environnement je crois).
    Sinon le reste du code m'a renvoyé sans surprise "é = c3a9"
    Citation Envoyé par corrector Voir le message
    Mince alors. J'ai l'habitude de lire les octets dans l'ordre.

    Là ça colle!
    Peut-être que ton éditeur hexa te remet les octets dans l'ordre pour que ce soit plus facile à lire, alors que le miens les sort brut de décoffrage.
    Si je me souviens bien ce qu'on m'a dit, cet inversion d'octet 2 par 2, c'est propre à tout les processeurs intel type x86 (AMD aussi du coup). Ce n'est pas le cas des processeur Sun, IBM et autre.


    En faisant des recherches, (assez laborieuses finalement. Je pensais trouver des informations plus facilement sur ce problème de base.) je suis tomber sur la classe ustring de la bibliothèque glibmm de gtk+.
    Dans la doc de cette bibliothèque j'ai lu ça:
    Glib::ustring has much the same interface as std::string, but contains Unicode characters encoded as UTF-8.

    [...]

    In a perfect world the C++ Standard Library would contain a UTF-8 string class. Unfortunately, the C++ standard doesn't mention UTF-8 at all. Note that std::wstring is not a UTF-8 string class because it contains only fixed-width characters (where width could be 32, 16, or even 8 bits).
    Donc le wstring que j'utilise ne gérerait pas totalement l'utf-8.
    Ça viendrait peut-être de là le problème!
    J'ai pas le temps tout de suite, mais je vais tester ça ce soir. Je vous tiens au courant.

  2. #42
    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 Endianness
    Citation Envoyé par wistiti1234 Voir le message
    Peut-être que ton éditeur hexa te remet les octets dans l'ordre pour que ce soit plus facile à lire, alors que le miens les sort brut de décoffrage.
    Les éditeurs hexa que j'ai utilisé affichent les octets dans l'ordre où ils se trouvent dans le fichier, tout simplement. C'est la seule façon correcte si on travaille au niveau des octets.

    Apparemment celui-ci travaille au niveau de paires d'octets. Pourquoi pas. Mais pourquoi pas travailler par 32, ou 64 bits? Ça me parait totalement arbitraire, et utile uniquement si on veut lire des données codées sur 16 bits en big-endian.

    Citation Envoyé par wistiti1234 Voir le message
    Si je me souviens bien ce qu'on m'a dit, cet inversion d'octet 2 par 2, c'est propre à tout les processeurs intel type x86 (AMD aussi du coup). Ce n'est pas le cas des processeur Sun, IBM et autre.
    Ou alors c'est Sun, Motorola, et les autres qui inversent et Intel qui n'inverse pas... C'est une question de codage : il ne s'agit pas de savoir qui inverse et qui n'inverse pas, mais de savoir comment est codé une information quand on doit la décoder. (Mais quand tu as un int, et que tu fais de l'arithmétique, tu te moques bien comment il est codé : le processeur le sait et c'est tout ce qui importe - en général tu n'as pas à t'occuper de ça.)

    Précisément, ce programme affiche 16 bits par 16 bits en commençant par le deuxième octet, donc si on interprète comme un entier de 16 bits écrit en hexa, cela ne correspond pas au codage des processeurs Intel. Sur Intel, un entier valant 2, lu octet par octet (par adresses croissantes) commence toujours par 02, puis autant de 00 qu'il reste d'octets : 02 00, ou 02 00 00 00 pour 16, ou 32 bits. C'est le codage little-endian; ça a l'avantage que quand on lit un long comme un short on trouve quand même la bonne valeur, si elle est représentable par un short; ça a le désavantage que quand on se trompe et qu'on lit un long comme un short on trouve la bonne valeur et on ne détecte pas l'erreur.

    De toutes manières, un fichier a un codage propre définit par sa spécification, qui ne dépend pas du processeur (heureusement) - sauf bien sûr les fichiers objet (et bibliothèques, et exécutables), qui dépendent totalement du processeur!

  3. #43
    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 basic_string vs. codage des caractères
    Citation Envoyé par wistiti1234 Voir le message
    Donc le wstring que j'utilise ne gérerait pas totalement l'utf-8.
    C'est une litote. wstring ne gère pas du tout l'UTF-8, pas du tout l'UTF-16, pas du tout l'UTF-32 etc.

    Rappel :
    wstring = basic_string<wchar_t>
    string = basic_string<char>

    basic_string<T> stocke des T. Il gère la mémoire, peut être initialisé par une suite de T terminée par un zéro...

    C'est tout. basic_string ignore tout du codage des caractères, et n'interprète rien.

    Tu peux utiliser string pour du iso-8859-*, pour de l'UTF-8, de l'UTF-16(LE|BE)...

    Sous linux, sizeof(wchar_t) = 4, et wstring est normalement de l'UCS-4. (Sous Windows, sizeof(wchar_t) = 2, wstring est généralement en UTF-16.)

    Dans tous les cas, une *string contient ce que tu as mis. Il faut savoir ce qu'on y met pour savoir quelles opérations ont un sens : quand tu écris :
    puisque ton source est en UTF-8 et que le compilateur ne fait aucune conversion (ce qui me surprend), s contient de l'UTF-8, donc l'opérateur d'indexation (operator[]) renvoie un octet qui n'a pas (toujours) de sens hors contexte (qui ne correspond pas à un "code-point", ou à un caractère). Donc tu ne peux ni utiliser les fonctions de classification isxxx, ni imprimer cette valeur toute seule avec cout.

    De plus, 'é' n'a pas le type char, mais int, parce que c'est un littéral multi-caractères et pas un littéral caractère, comme tu as vu.

    Si tu utilisais un codage mono-caractère comme iso-8859-*, tu pourrais indexer ta chaine et utiliser les fonctions isxxx et to(lower|upper).

    Dans l'affaire, string est complètement neutre.

    La norme ne spécifie aucun codage de caractère particulier, ni pour char, ni pour wchar_t. (Même le codage en ASCII des caractères qui sont ASCII n'est pas obligatoire.) D'ailleurs il est utile d'avoir le choix du codage de char. (La multiplicité des codages de wchar_t est un artéfact historique, ça devrait toujours être UCS-*.)

    Les entrée-sorties en C++ sont définies comme mono-char : la norme considère que le système traite les E/S de cette façon. std::cout sort directement (sans conversion) ce qui lui est envoyé (c'est pour ça que le dump "inversé" m'a grandement perturbé!).

    Les E/S en wchar_t dont définies par conversion de wchar_t en char, la conversion effectuée dépendant du codage, qui comme je l'ai dis, dépend de l'implémentation (et de la locale).

    Ici, la locale étant UTF-8, wcout devrait convertir de l'UCS-4 en UTF-8.

  4. #44
    Invité
    Invité(e)
    Par défaut Complément
    Citation Envoyé par corrector Voir le message
    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!)
    Tous les caractères de ton message existent dans le jeu ISO 8859-15...

    Il te manquerait quel caractère par exemple dans l'ISO 8859-15 pour écrire français ?

  5. #45
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Attention, ISO 8859-15, c'est Latin-9, pas Latin-1...

  6. #46
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 118
    Points : 176
    Points
    176
    Par défaut
    Finalement j'ai eu un week-end très chargé, j'ai pas pu avancer beaucoup.
    Mais j'ai quand même pu testé les ustring, mais ça ne s'affiche pas mieux (au moins ça m'affiche un message d'erreur clair cette fois "terminate called after throwing an instance of 'Glib::ConvertError'
    Abandon
    si il y a un caractère accentué dans la chaîne, sinon ça marche)

    Cela dit je crois que les ustring me seront quand même indispensable pour pouvoir sortir des caractères de mes chaînes, ce que j'aurais énormément besoin de faire dans mon programme. Donc c'est bien que je soit tombé là-dessus.


    Pour le coeur de mon problème, je crois que la solution se trouve dans les locales. Il va falloir que je me documente là-dessus cette semaine parce que c'est encore assez flou pour moi. Vous n'auriez pas un site didacticiel qui présenterais cela clairement?

    D'ailleurs merci pour tes explications corrector, ça m'a déjà éclaircit l'esprit.

  7. #47
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 118
    Points : 176
    Points
    176
    Par défaut
    Ok donc fallait juste écrire
    au début de mon programme.

    Ça a l'air bête, mais quand on sait pas, il y a quasiment aucun moyen de le savoir puisqu'Il n'y a quasiment aucune doc ou site qui en parle sur le net

    J'espère juste que si il y a d'autre novices sont bloqué par ce même problème, qu'il vont rapidement tomber sur ce fil dans leurs recherches.

  8. #48
    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,

    Comment faire pour saisir un wstring au clavier.

    wstring z ;
    getline( cin, z ) => ça passe pas

    Comment faire ?

  9. #49
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858

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

Discussions similaires

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

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