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 :

conversion - char to wchar_t


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Septembre 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 15
    Points : 13
    Points
    13
    Par défaut conversion - char to wchar_t
    Salut tout le monde,

    C'est certainement une questions simple pour la plupart d'entre vous, mais je bloque...

    Je dois convertir un char en wchar_t... dans la fonction "main" de mon programme, j'ai réussi à le faire grâce à MSDN:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char* orig = "Hello, World!";
    // Convert to a wchar_t*
    size_t origsize = strlen(orig) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE);
    wcout << wcstring << endl;
    Jusque là... OK...

    maintenant j'aimerais créer une fonction "convert" qui utilise ce code, en prenant la variable char* en paramètre pour retourner le wchar_t

    La raison pour laquelle je veux faire ceci étant simple: je dois convertir à de maintes reprises dans le programme. (projet d'intégration oblige)...

    J'ai essayé ceci mais sans succès. Pas de compilation error mais il me retourne toujours "52428" comme valeur pour la variable wchar_t...

    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
     
    wchar_t convert(char* orig) {
        size_t origsize = strlen(orig) + 1;
        const size_t newsize = 100;
        size_t convertedChars = 0;
        wchar_t wcstring[newsize];
        mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE);
        return wcstring[newsize];
        //wcout << wcstring << endl;
    }
     
    int main(int argc, char *args[])
    {
    char* orig = "Hello, World!";
    wchar_t wcstring = convert(orig);
     
    cout << orig << " --> AS A CHAR..." << endl;
    cout << wcstring << " --> AS A WCHAR_T...";
    }
    Quelqu'un sait pourquoi?? ce doit être une bêtise vu que ça fonctionne quand je fais ça manuellement dans le "main"...

    thanks for ur help

    Olivier

  2. #2
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 593
    Points
    41 593
    Par défaut
    Tu dois retourner un pointeur vers un buffer nouvellement alloué sur le tas. Pour connaître la taille à allouée, tu dois utiliser mbstowcs() avec un buffer de sortie nul et une taille de sortie nulle...
    Et aussi, donner une fonction pour détruire le buffer alloué.
    Typiquement un truc de ce genre:
    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
    //Fonctions d'allocation et suppression
    char * StrAllocThrowA(size_t cchSize)
    {
    	return new char[cchSize];
    }
    wchar_t * StrAllocThrowW(size_t cchSize)
    {
    	return new wchar_t[cchSize];
    }
    void StrFreeA(char * s)
    {
    	delete[] s;
    }
    void StrFreeW(wchar_t * s)
    {
    	delete[] s;
    }
     
    //Surcharge C++, plus simple.
    inline void StrFree( char   * s) { return StrFreeA(s); }
    inline void StrFree(wchar_t * s) { return StrFreeW(s); }
     
    //Fonctions de conversion
    wchar_t * ambstowcs(char const *sczA)
    {
    	size_t const cchLenA = Length(sczA);
    	size_t const cchLenW = mbstowcs(NULL, sczA, cchLenA+1);
    	wchar_t * szW = StrAllocThrowW(cchLenW+1);
    	mbstowcs(szW, sczA, cchLenA+1);
    	return szW;
    }
    char * awcstombs(wchar_t const *sczW)
    {
    	size_t const cchLenW = Length(sczW);
    	size_t const cchLenA = wcstombs(NULL, sczW, cchLenW+1);
    	char * szA = StrAllocThrowA(cchLenA+1);
    	wcstombs(szA, sczW, cchLenW+1);
    	return szA;
    }
    Notes sur ma notation:
    • A est pour "ASCII Étendu" (char), W est pour "Wide" (wchar_t).
    • cch indique une taille en caractères, par opposition à cb qui indique une taille en octets (très important quand on parle de wchar_t).
    • len indique une longueur sans le zéro terminal (contrairement à size)

    Utilisation: On convertit en wchar_t avec ambstowcs(), et on détruit la chaîne avec StrFreeW() ou StrFree().

    Edit: Note: En théorie, une exception std::bad_alloc est lancée en cas d'échec de new (s'il n'y a plus assez de mémoire).

  3. #3
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 593
    Points
    41 593
    Par défaut
    Suite à ta requête par MP, j'explique mon code:
    • J'ai écris les fonctions StrAllocXX et StrFreeXX pour "isoler" l'allocation de mémoire. Comme ça, si un jour on décide d'utiliser une autre méthode d'allocation que new et delete (par exemple, des fonctions du système, ou de la mémoire partagée), on n'aura à modifier que ces fonctions-là.
    • Une obligation en C et C++ est que ce qui est alloué par un "module" (sous Windows, "module" désigne les EXE et les DLL) doit être détruit par le même module. Donc, par réflexe, je définis une fonction de destruction (les StrFreeXX) dans le même fichier source que les fonctions qui font l'allocation (StrAllocXX et les fonctions de conversion).
    • L'allocation se fait en deux étapes: D'abord, on appelle mbstowcs sans lui donner de buffer de sortie, juste pour connaître la taille à allouer (la version C99 de la fonction C snprintf() permet la même chose, mais n'existe pas sous Visual). Ensuite, on alloue la taille demandée et on rappelle la fonction en lui passant cette fois-ci un pointeur sur la mémoire allouée.
    • Beaucoup de fonctions de Windows suivent la même philosophie, d'ailleurs...
    • J'ai appelé la fonction de conversion ambstowcs(). J'ai pris cette idée grâce à un vieux système FreeBSD qui proposait une fonction asprintf() pour aller avec la fonction C sprintf(). Le "a" est l'initiale de "allocation", signifiant que la fonction alloue la mémoire qu'elle retourne. Le code qui utilise la fonction doit donc appeler une fonction de suppression quand il n'a plus besoin de la mémoire retournée.

  4. #4
    Membre à l'essai
    Inscrit en
    Septembre 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 15
    Points : 13
    Points
    13
    Par défaut suite
    Hey médinoc,

    Merci pour ta réponse. J'ai essayé en utilisant les méthodes que tu m'as décrites. Voici ce que j'ai utilisé:

    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
     
    //Fonctions d'allocation et suppression
    char * StrAllocThrowA(size_t cchSize)
    {
    	return new char[cchSize];
    }
    wchar_t * StrAllocThrowW(size_t cchSize)
    {
    	return new wchar_t[cchSize];
    }
    void StrFreeA(char * s)
    {
    	delete[] s;
    }
    void StrFreeW(wchar_t * s)
    {
    	delete[] s;
    }
     
    //Surcharge C++, plus simple.
    inline void StrFree( char   * s) { return StrFreeA(s); }
    inline void StrFree(wchar_t * s) { return StrFreeW(s); }
     
    //Fonctions de conversion
    wchar_t * ambstowcs(char const *sczA)
    {
    	size_t const cchLenA = strlen(sczA);
    	size_t const cchLenW = mbstowcs(NULL, sczA, cchLenA+1);
    	wchar_t * szW = StrAllocThrowW(cchLenW+1);
    	mbstowcs(szW, sczA, cchLenA+1);
    	return szW;
    }
     
    int main(int argc, char *args[])
    {
    	char* orig = "Hello, World!";
            wchar_t *wcstring = ambstowcs(orig);
     
    	cout << orig << " --> AS A CHAR..." << endl;
    	cout << wcstring << " --> AS A WCHAR_T...";
            system("PAUSE");
    Ca compile, ça se lance mais je n'obtiens toujours pas "Hello, World!" dans ma wchar_t car voici ce qu'il m'output:

    Hello, World! --> AS A CHAR...
    00365F90 --> AS A WCHAR_T...

    Je me suis trompé quelque part?

    Olivier

  5. #5
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 593
    Points
    41 593
    Par défaut
    Je ne sais pas trop pourquoi, mais tu n'utilises plus wcout...

    De plus, tu dois détruire wcstring avec la fonction StrFree() une fois que tu n'en as plus besoin.

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int main(void)
    {
    	char const * orig = "Hello, World!";
    	wchar_t *wcstring = ambstowcs(orig);
     
    	cout << orig << " --> AS A CHAR..." << endl;
    	wcout << wcstring << L" --> AS A WCHAR_T..." << endl;
    	StrFree(wcstring), wcstring = NULL;
     
    	system("PAUSE");
    	return 0;
    }

  6. #6
    Membre à l'essai
    Inscrit en
    Septembre 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 15
    Points : 13
    Points
    13
    Par défaut fonctionne! mais...
    thanks pour ta réponse rapide!

    ça fonctionne. merci!

    juste encore un truc... il m'affiche 2 warnings quand je run:

    Warning 1 warning C4996: 'mbstowcs': This function or variable may be unsafe. Consider using mbstowcs_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

    Warning 2 warning C4996: 'mbstowcs': This function or variable may be unsafe. Consider using mbstowcs_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

    dois-je m'en inquièter?

    olo

  7. #7
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 593
    Points
    41 593
    Par défaut
    • Si tu veux que ton code reste standard, non, du ne dois pas t'en inquiéter.
      Tu peux rajouter _CRT_SECURE_NO_WARNINGS dans les options du préprocesseur (Project Properties -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions).
    • Si tu veux respecter le non-standard de microsoft, tu devras faire les modifications appropriées pour utliiser mbstowcs_s() et wcstombs_s(), et tu ne pourras plus compiler avec autre chose que Visual.
      Attention, la taille retournée par les versions _s est différente de celles retournées par les versions standard: Les version _s prennent en compte le zéro terminal.

    PS: Ces warnings s'affichent quand tu compiles, pas à l'exécution.

  8. #8
    Membre à l'essai
    Inscrit en
    Septembre 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 15
    Points : 13
    Points
    13
    Par défaut résolu
    OK. Merci, alors je laisse tel quel

    Merci encore pr ton aide.

    Olivier

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

Discussions similaires

  1. Conversion char* (UTF-8) en wchar_t*
    Par IMS dans le forum C
    Réponses: 10
    Dernier message: 21/10/2009, 12h06
  2. conversion char wide char
    Par ep31 dans le forum MFC
    Réponses: 4
    Dernier message: 15/11/2005, 09h14
  3. Pb Invalid Conversion "char" to "char*"
    Par kazarn dans le forum C++
    Réponses: 3
    Dernier message: 02/03/2005, 14h24
  4. Conversion char * vers wchar_t
    Par Zapan dans le forum C++
    Réponses: 4
    Dernier message: 24/02/2005, 16h56
  5. Réponses: 3
    Dernier message: 27/05/2004, 00h03

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