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 :

wchar_t, problème compatibilité Windows/Linux


Sujet :

C

  1. #1
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut wchar_t, problème compatibilité Windows/Linux
    Bonjour...
    J'ai toujours des problèmes avec l'UNICODE
    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
     
    #include <stdio.h>
    #include <locale.h>
    #include <wchar.h>
     
    #define E_AIGU_MIN L'\x00E9'
     
    int main(void){
      wint_t c;
      setlocale(LC_ALL,"");
      c = getwchar();
      if (c == E_AIGU_MIN)
         c = L'e';
      putwchar(c);
      return 0;
    }
    Ce que je voudrais, c'est que si je tape un 'é' , il m'affiche un 'e'. J'ai récupéré le code Unicode du 'é' depuis cette page http://www.unicode.org/fr/charts/PDF/U0080.pdf

    Ce code fonctionne bien sous mon Linux (Ubuntu), mais PAS sous Windows, où cela m'affiche un deuxième 'é' après celui que j'ai tapé.
    J'arrive pas bien à comprendre pourquoi... J'ai essayé d'enlever le setlocale, ça ne change rien. A croire que le 'é' n'a pas ce codage sous Windows.

    Comment je pourrais remédier à ce problème?

  2. #2
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Tu n'as pas poussé tes investigations très loin. Je suis sous Windows. J'ai inséré un printf dans ton code. Pour un 'é' avec la locale, je trouve 201a, et 82 sans la locale.

    A+

    Pfeuh

    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
    #include <stdio.h>
    #include <locale.h>
    #include <wchar.h>
     
    #define E_AIGU_MIN L'\x00E9'
     
    int main(void){
      wint_t c;
      //setlocale(LC_ALL,"");
      c = getwchar();
      printf("%x\n",c);
      if (c == E_AIGU_MIN)
         c = L'e';
      putwchar(c);
      return 0;
    }

  3. #3
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut
    Merci pour ta réponse, Pfeuh !

    J'ai inséré un printf dans ton code. Pour un 'é' avec la locale, je trouve 201a, et 82 sans la locale.
    Effectivement, j'ai les mêmes résultats que toi.

    En fait ma question portait surtout sur le fait de comment rendre portable mon programme.
    Est ce qu'il y aurait un moyen de faire quelque chose du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #if MACRO_QUI_INDIQUE_QUE_LON_EST_SOUS_UNIX
    #define E_AIGU_MIN L'\x00E9'
    #else /*Si on est sous windows*/
    #define E_AIGU_MIN L'\x201a'
    #endif
    Et ainsi mon code serait, à priori, portable. Ca existe ce genre de macro?

    Ou alors, peut on écrire modifier la locale toujours de la même manière, pour que, quel que soit l'OS utilisé, ce soit la même valeur qui soit prise en compte pour le caractère 'é'.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    setlocale(LC_ALL,"truc commun");
    C'est faisable ça?

  4. #4
    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
    Vraiment étrange.

    Sans le setlocale(), quand je tape "é" sur une console Windows, j'obtiens 0x0082 ("é" en encodage IBM-850).
    Avec, j'obtiens 0x201a, qui correspond à 'SINGLE LOW-9 QUOTATION MARK' (U+201A)

    Edit: et si je change la codepage vers 1252 avant d'exécuter le programme, j'obtiens 0xE9 dans tous les cas.
    Edit2: Et remplacer getwchar() par ReadConsoleW() ne change rien.

  5. #5
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut
    Edit: et si je change la codepage vers 1252 avant d'exécuter le programme, j'obtiens 0xE9 dans tous les cas
    Intéressant ça^^. Mais c'est quoi au juste le codepage ? Et comment le modifier?

  6. #6
    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
    C'est la page de codes utilisée pour la console. Le charset, quoi.

    Sur l'invite de commandes, tu peux utiliser ceci:
    Code Cmd : Sélectionner tout - Visualiser dans une fenêtre à part
    mode con codepage select=1252
    Mais apparemment, on peut aussi simplement faire:

    La page 1252, aussi connue comme "charset Windows-1252", c'est la page de codes utilisée par défaut en occident sous Windows. C'est un dérivé de l'ISO 8859-1 Latin-1, où certains codes de contrôle supérieurs sont remplacés par des caractères affichables (notamment le symbole Euro).

    Par défaut, en Europe occidentale, la console utilise la page de codes 850 à la place: C'est ce qu'utilisait DOS en Europe occidentale.
    Aux états-unis, la page de codes utilisée est plutôt la 437, qui ne contient pas d'accents (à la place, elle contient les caractères de dessin "mixtes").

  7. #7
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut
    Merci Medinoc
    Ce que tu dis a l'air de fonctionner. Il m'affiche bien un 'e', sauf que quand je tape 'é', c'est un 'ù' qui s'affiche !
    En fait, j'aimerais bien pouvoir régler mon problème sans passer par une commande sur la console avant.
    Je cherche toujours, pas sur que je trouve...
    J'ai regardé le resultat de setlocale(LC_ALL,"")
    J'obtiens évidemment pas la meme chose sous Unix que sous windows. Sous windows, c'est "French_France.1252". Enfin à quoi ça m'avance, je sais pas trop...
    Ca doit bien être possible de faire ça de manière portable non?

    edit : et sous ubuntu, "fr_FR.UTF-8"

  8. #8
    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
    Citation Envoyé par Climoo Voir le message
    Merci Medinoc
    Ce que tu dis a l'air de fonctionner. Il m'affiche bien un 'e', sauf que quand je tape 'é', c'est un 'ù' qui s'affiche !
    Le changement de locale n'a pas d'effet visible sur la console tant qu'elle est réglée en "polices raster": Il faut en plus aller dans les propriétés de la console et changer la police en "Lucida Console".
    Il y a des fonctions pour faire ça, mais elles ne sont pas exposées ni documentées. Je me souviens qu'il y avait un tuto sur le net pour les utiliser...

    Par contre, si la console est déjà en police Lucida Console, tu peux faire l'équivalent du chcp dans ton programme même: Les fonctions SetConsoleCP() et SetConsoleOutputCP() sont là pour ça.

    En fait, j'aimerais bien pouvoir régler mon problème sans passer par une commande sur la console avant.
    Je cherche toujours, pas sur que je trouve...
    J'ai regardé le resultat de setlocale(LC_ALL,"")
    J'obtiens évidemment pas la meme chose sous Unix que sous windows. Sous windows, c'est "French_France.1252". Enfin à quoi ça m'avance, je sais pas trop...
    Ca doit bien être possible de faire ça de manière portable non?

    edit : et sous ubuntu, "fr_FR.UTF-8"
    Hélas, les noms de locale autres que "C" et "" ne sont pas portables.

  9. #9
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut
    Merci Medinoc (heureusement que tu es là).
    J'ai remarqué les fonctions SetConsoleCP() et SetConsoleOutputCP() sont disponibles seulement sous windows, car il faut inclure le fichier "windows.h".
    Je suis donc toujours un peu embêté si je veux que ça fonctionne des deux côtés...
    Donc ce que je vais faire, sauf si je trouve mieux, c'est faire une compilation conditionnelle. A la compilation, il faudra spécifier une variable OS par exemple, et dans mon code j'aurai des trucs du type.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #if  OS == ...
    ...
    #else
    ...
    #endif
    Comme je trouve pas de macro qui représente ça déjà définie ailleurs...
    C'est sûr, c'est pas ce qu'il ya de mieux, mais en attendant, j'espère que ça fera l'affaire.

    Merci pour tout

  10. #10
    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
    #ifdef WIN32 (ou _WIN32, je ne sais plus) marche généralement très bien sous Windows... Y compris en 64 bits.

  11. #11
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut
    Ah! Encore mieux
    Encore merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 18/05/2009, 02h43
  2. Réponses: 1
    Dernier message: 04/08/2008, 23h42
  3. Compatibilité Windows / Linux
    Par grinder59 dans le forum Administration système
    Réponses: 2
    Dernier message: 28/08/2007, 11h27
  4. les Threads (compatibilité Windows / Linux)
    Par ramislebob dans le forum C
    Réponses: 14
    Dernier message: 28/07/2006, 11h26
  5. Compatibilité Windows/linux
    Par ChriGoLioNaDor dans le forum C++
    Réponses: 5
    Dernier message: 10/01/2006, 00h39

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