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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 15
    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
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    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).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    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.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 15
    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
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    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;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 15
    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

+ 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, 11h06
  2. conversion char wide char
    Par ep31 dans le forum MFC
    Réponses: 4
    Dernier message: 15/11/2005, 08h14
  3. Pb Invalid Conversion "char" to "char*"
    Par kazarn dans le forum C++
    Réponses: 3
    Dernier message: 02/03/2005, 13h24
  4. Conversion char * vers wchar_t
    Par Zapan dans le forum C++
    Réponses: 4
    Dernier message: 24/02/2005, 15h56
  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