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 :

char*, string et wstring


Sujet :

C++

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    230
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 230
    Par d�faut char*, string et wstring
    Bonjour � tous !

    Bon je sais ce que vous pensez : c'est un marronnier... Mais j'ai beau avoir lu une bonne centaine de topics � ce sujet ainsi que la FAQ de developpez.com et pourtant je n'arrive toujours pas � comprendre ce qui se passe dans mon cas...

    Je r�cup�re apr�s une appel � une fonction d'une librairie un .
    Cette variable contient la chaine suivante :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Bibliothèque de « Esteban
    or elle devrait contenir :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Bibliothèque de "Esteban
    .

    Je suppose donc qu'il s'agit d'une chaine encod�e en UTF-8 avec des caract�res de 16bits. Sauf que quand je parcours le tableau de char j'ai la liste suivante :
    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
    char B (66)
    char i (105)
    char b (98)
    char l (108)
    char i (105)
    char o (111)
    char t (116)
    char h (104)
    char(-61) //Le caractère est modifié dans le post il s'agit d'un symbole coché
    char ® (-88)
    char q (113)
    char u (117)
    char e (101)
    char   (32)
    char d (100)
    char e (101)
    char   (32)
    char ¬ (-62)
    char ´ (-85)
    char ¬ (-62)
    char(-96)
    Je m'attendais � avoir les caract�res √ et � regroup�s en un seul caract�re qui, converti en wchar_t deviendrait un �...

    J'en conclus donc que j'ai rien entrav� au truc et que je ne sais absolument pas comment m'en sortir...

    Quelqu'un peut-il m'�clairer un peu s'il vous plait ?

  2. #2
    screetch
    Invit�(e)
    Par d�faut
    UTF-8 est un encodage a longueur variable, ou les symboles "simples" (a-z et la ponctuation) sont cod�s sur un seul octet (compatible avec la norme ANSI) et les symboles "complexes" (lettres accentu�es spe�cifiques a une langue, id�ogrammes et alphabets plus exotiques) sont encod�s sur plusieurs octets (de 2 a... 6 je crois)

    la cha�ne n'est donc ni une string (qui est seulement ANSI) ni une wstring (qui repr�sente une cha�ne UCS-2 ou UCS-4 ou UTF16 selon les cas)

    Ces trucs grossiers (UTF-8, UCS-2 UCS-4 UTF-16, ANSI...) sont des encodages. Les questions sont donc:

    - quel encodage as-tu?
    * tu as de l'UTF-8 dans cet exemple mais cela depend il de la source? d'ou vient cette cha�ne?
    - quel encodage veux tu?
    * tu veux de l'encodage naturel de ta machine par exemple?
    * ou bien tout convertir en wstring?
    - quel systeme d'exploitation utilises-tu?


    il se peut que tu doives utiliser des biblioth�ques tierces pour que ca marche.

  3. #3
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 295
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 4 295
    Billets dans le blog
    2
    Par d�faut
    C'est compliqu� ces histoires d'encodages, je ne suis jamais parvenu � y voir clair. Par exemple, la s�rie des visual studio, depuis la version 7 me semble-t-il, propose une option pour les projets qui est le jeu de carract�res (unicode ou multibyte). Qu'est-ce donc que cela?
    Aurais-tu des liens qui expliquent bien ces choses-l�?

  4. #4
    Membre confirm�
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    230
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 230
    Par d�faut
    Ah ben je commence � mieux comprendre mes probl�mes...
    Pour r�pondre � tes questions :
    -ce cas pr�cis se pr�sente � l'appel de la fonction DNSServiceBrowse de la librairie Bonjour (dns_ns). Je ne connais pas l'encodage, il n'est pas pr�cis� mais je pr�sume que c'est celui du syst�me qui envoie son nom depuis le r�seau. Il doit donc y avoir un m�lange entre MacRoman dans certains cas et UTF-8 dans d'autres.
    -je veux pouvoir interpr�ter ces chaines provenant de diff�rents syst�mes et encod�es dans des formats qui ne me sont pas connus a priori et les mettre dans ma base dans un format string (pas wstring)...
    -je voudrais que mon code soit le m�me sous Windows, Mac et Linux (ou faire une fonction filtr�e par des #ifdef).

    Quelle librairie me sugg�res-tu ?

    Merci pour vos r�ponses

  5. #5
    screetch
    Invit�(e)
    Par d�faut
    dans Windows il y a pour simplifier 2 encodages:

    * l'encodage courant de l'utilisateur qui se traduit par un char*
    * l'encodage appel� a tort Unicode qui est l'encodage UCS-2 (pas le choix), et qui mappe sur des wchar_t de deux octets


    Le flag Multibyte/Unicode permet en fait de changer entre un encodage "local" (par exemple, du francais) et un encodage UCS-2 lors de l'appel des m�thodes Windows
    (pour faire simple, les m�thodes qui attendent en param�tre des strings recoivent soit des char*, soit des wchat_t*). Utiliser la version MultiByte revient a dire que l'application d�pend de la locale courante, et est donc pas "Unicode-aware", donc ne recevra pas l'input windows unicode (si on essaye de taper du chinois, ca marche p�)

    lorsqu'on passe en unicode, tous les param�tres de fonction sont maintenant des wchar_t* donc encod�s en UCS-2
    et utiliser la version unicode signifie que l'application doit d�sormais savoir utiliser l'unicode et recevra d�sormais l'input sous forme Unicode (donc si on tape du chinois, le charactere chinois sera pass� a l'application)

    et il y a quelques fonctions de conversion qui permettent de passer de certains encodages a d'autres.
    par exemple, MultibyteToWideChar peut passer d'une chaine encod�e en multibyte (en UTF-8, ou bien dans l'encodage courant) vers de l'UCS-2
    et WideCharToMultiByte fait le contraire.

    Dans une application Widows moderne (sous-entendu, supportant plusieurs langages), l'application doit �tre regl�e en Unicode et traiter la plupart des cha�nes en interne en wchar_t, quitte a r�interpreter certaines chaines entr�es par l'utilisateur via MultibyteToWideChar.

  6. #6
    Membre chevronn�

    Inscrit en
    Ao�t 2007
    Messages
    300
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2007
    Messages : 300
    Par d�faut
    Je pense que screetch couvre compl�tement votre probl�me et y apporte les meilleurs solutions (en particulier je recommande effectivement de ne pas avoir de UTF-8/multibyte en stockage interne, le c�ur du programme devant �tre UTF-16/UCS-2 du point de vue Windows, c'est � dire wchar_t/std::wstring du point de vue C++. Oui, j'utilise xxx/yyy, car pour embrouiller tout le monde, il y a en plus des probl�mes de synonymes! A quand un nommage "unifi�" pour d�signer UTF-16/UCS-2? Ah oui, �a existe d�j�, �a s'appelle Unicode "sans plus de pr�cision d'encodage" je crois... du moins chez Microsoft, mais bien s�r pas pour les chinois )

    Pour le contexte, Joel Spolsky a pondu dans son style inimitable il y a d�j� longtemps un petit texte d'introduction vraiment clair, que je file dans le paquet de bienvenue aux stagiaires. Bien que ce texte soit dat�, avec sa seule connaissance, on peut se d�patouiller d'un grand nombre de cas r�els.

  7. #7
    Membre confirm�
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    230
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 230
    Par d�faut
    Formidable merci beaucoup pour toutes ces infos !

    Je vais devoir faire un peu de conception pour m'adapter � ces nouvelles (pour moi) r�gles. J'ai imprim� le petit article et je vais m'attaquer � des essais. Si je suis bloqu� je reviendrai vous voir !

    Merci encore.
    Esteban

  8. #8
    screetch
    Invit�(e)
    Par d�faut
    salut esteban, j'avais rat� ta premi�re r�ponse car je postais au m�me moment.
    Sous MacOS je crois (mais je suis pas 100% s�r) que l'API de conversion entre encodages est iconv, comme sous linux et BSD. Avec ca tu peux convertir entre UTF-8 et tout ce que tu veux.
    Et dans le cas Linux/BSD/Solaris il est plut�t conseill� d'utiliser un encodage UTF-8 en interne (car plus compact) et de traduire vers l'encodage utilis� sur la machine si on en a besoin. En fait sous linux avec iconv il est vraiment possible de choisir n'importe quel encodage unicode.
    Dans le cas Windows, c'est wchar_t et donc UCS-2
    dans le cas MacOSX je pense que tu peux choisir aussi, je crois que NSString en interne utilise unichar qui est UCS-2 mais je suis pas 100% s�r.

    Mais disons que l'id�e g�n�rale pour supporter tout et n'importe quoi, c'est
    input utilisateur -> conversion Unicode (n'importe lequel, le plus pratique) -> traitements, copies, blabla -> conversion Encodage local (Chinois, Japonais, Francais... voire unicode parfois ) -> affichage

  9. #9
    Membre confirm�
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    230
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 230
    Par d�faut
    Ok j'entends bien vos conseils et je vais t�cher de bien convertir toutes mes entr�es dans un format unique (mettons UTF8) pour ma bdd et de reconvertir les chaines stock�es dans le format utilis� par le syst�me pour la restitution.

    En revanche ce que je m'explique moins bien c'est comment je d�tecte le format en entr�e. Mes entr�es sont diverses et sont le plus souvent le fait de communications r�seau d'origines diverses (Windows, Mac, Linux, T�l�phone, etc...), du coup je ne connais pas n�cessairement le format d'encodage en entr�e. Y a-t-il un moyen de le d�tecter ou bien je dois le deviner ? Si je convertit ce que je croyais �tre du MacRoman en UTF8 dans ma bdd et qu'ensuite je le reconverti en UCS-2 pour l'afficher dans l'IHM, je vais afficher des symboles � la con non ?

  10. #10
    screetch
    Invit�(e)
    Par d�faut
    tes communications r�seau, sans en savoir plus, c'est pas possible de savoir en quoi elles sont encod�es.
    Si c'est toi qui les contr�le c'est facile, c'est toi qui d�cide.
    Si ca vient du systeme d'exploitation, ca doit �tre avec la locale courante. essaye:
    dans un terminal pour avoir l'encodage courant? si c'est de l'UTF-8 il y a des chances que ca soit pour ca que tu recois des cha�nes en UTF-8.
    Enfin si ca vient d'une lib externe, il faut voir la doc de cette biblioth�que pour savoir ce qu'elle renvoie.

  11. #11
    Membre confirm�
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    230
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 230
    Par d�faut
    Pour compl�ter mon premier exemple, mettons que je re�oive gr�ce � la m�me requ�te (Service Discovery de Bonjour) 2 chaines provenant pour l'une d'une machine sous Windows 7 et l'autre d'une machine sous Mac OS.

    Il n'est �crit nulle part dans la doc de DNS_SD que la chaine est encod�e d'une certaine mani�re.

    Tout ce que je re�ois est un char* dans ma fonction callback. Du coup j'ai 2 options : soit je consid�re que c'est encod� par la librairie dans l'encodage du syst�me sur lequel tourne la librairie (ce qui serait logique puisque j'imagine mal la m�me librairie encoder en MacRoman sous Windows), soit je consid�re que la librairie n'encode rien et qu'elle laisse la chaine telle qu'envoy�e par le syst�me qui a r�pondu... ce qui pourrait signifier que dans un cas j'ai de l'UCS-2 et dans l'autre du MacRoman... Arff je m'en sors pas... Il faut que je fasse des essais de conversion pour en savoir plus.

    Penses-tu simplement qu'il est possible qu'une chaine char* puisse contenir du texte encod� dans des formats 2 octets (UCS-2 par exemple) ?

    Je fais des essais avec iconv et je vous tiens au courant.

  12. #12
    screetch
    Invit�(e)
    Par d�faut
    a priori non, sous MacOS une chaine UCS-2 est une chaine unichar*
    mais tout est possible hein
    la c'est au dela de mes connaissances, il faut trouver de la doc sur cette biblioth�que ou quelqu'un qui s'en est deja servi et qui sait.

  13. #13
    Membre confirm�
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    230
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 230
    Par d�faut
    Mazel'tov !!

    J'ai r�ussi... et je vais expliquer ici comment j'ai fait, ca pourra aider quelqu'un d'autre et ca vous permettra de me corriger si je dis des b�tises

    Je me suis rendu compte que la chaine en entr�e est bien encod�e en UTF-8, il fallait donc que je l'encode dans le style local (MacRoman pour moi).

    Le code : c'est inline, je n'ai pas fait de fonction pour le moment
    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
     
    char *instr = const_cast<char *>(serviceName);
    char *_strout = new char(strlen(serviceName)*2);
    char *strout = _strout;
     
    size_t nconv = 0;
    size_t instrlen = strlen(serviceName);
    size_t outstrlen = instrlen*2;
     
    iconv_t ic = iconv_open("MACROMAN", "UTF-8");
    if(ic != (iconv_t)-1) {
    	nconv = iconv(ic, &instr, &instrlen, &strout, &outstrlen);
     
    	if(nconv != (size_t)-1) {
    		cout << "strout=" << _strout << endl;
                    delete [] _strout;
    	} else
    	**    cerr << "error : " << errno << "-" << strerror(errno) << endl;
    } else
         cerr << "error : " << strerror(errno) << endl;

  14. #14
    Membre confirm�
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    230
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 230
    Par d�faut
    En gros maintenant ce qu'il me reste � faire c'est stocker la chaine re�ue sans la modifier puisqu'elle est en UTF-8, et utiliser la conversion � chaque fois que je veux afficher cette chaine...

    C'est bien ca ?

  15. #15
    screetch
    Invit�(e)
    Par d�faut
    ca d�pend de l'affichage. Les NSString de l'API MacOS graphique sont en UCS-2 je crois, mais elles ont le bon go�t de faire leur propre conversion
    La console en revanche, ca d�pend de la machine utilisateur.
    Note que si toi tu as du MacRoman, a propri un chinois en chine aura pas du MacRoman et qu'il vaudrait mieux effectuer la conversion vers l'encodage "utilis� en ce moment sur la machine". Je ne sais pas trop comment le r�cup�rer.
    Si c'est en graphique alors file le a NSString et laisse le faire

Discussions similaires

  1. char, string, wchar_t, wstring ?
    Par Invit� dans le forum SL & STL
    R�ponses: 8
    Dernier message: 22/10/2014, 22h32
  2. Transtypage int => char, String => char
    Par autregalaxie dans le forum D�buter avec Java
    R�ponses: 7
    Dernier message: 10/04/2007, 13h48
  3. string et wstring
    Par superspag dans le forum C++
    R�ponses: 7
    Dernier message: 20/01/2006, 08h31
  4. char *, string et tableau statique ou dynamique
    Par salseropom dans le forum C
    R�ponses: 2
    Dernier message: 05/12/2005, 11h33
  5. R�ponses: 3
    Dernier message: 26/05/2004, 23h03

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