IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > CString et Conversions
        Comment convertir un BSTR en chaîne ordinaire et vice-versa ?
        Comment convertir une CString en int, double, long ?
        Comment convertir une CString vers une std::string et vice et versa ?
        Comment convertir des chaînes hexa en integer, inversement et plus largement comment changer la base d'une valeur dans une string ?
        Quel est le nombre de caractères maximum que peut contenir une CString ?
        Comment faire une extraction dans une CString avec des séparateurs ?
        Comment créer une chaîne de type BSTR ?
        Comment concaténer 2 BSTR ?
        Comment libérer une chaîne de type BSTR ?
        Comment convertir un entier, un double, un float, etc, en chaîne de caractères ?
        Comment convertir des chaînes de caractères en ANSI et en UNICODE avec les MFC ?
        Comment convertir une CString ?
        Comment récupérer directement le contenu d'un contrôle dans un entier,double,long, etc.?
        Comment affecter directement le contenu d'une variable de type int,long,double ... à un contrôle ?
        Comment encoder une chaîne au format UTF8 ?
        Comment décoder une chaîne au format UTF8 ?
        Comment convertir une chaîne UNICODE en Char * ?



Comment convertir un BSTR en chaîne ordinaire et vice-versa ?
auteur : nico-pyright(c)
Si vous développez des ActiveX ou objets COM avec Visual C++, vous allez devoir utiliser les BSTR lors de manipulation de chaînes de caractères.
Le type BSTR (Basic STRing) est un pointeur de 32 bits (comme tous les pointeurs) qui pointe vers un tableau de caractères UNICODE.
En représentation UNICODE, 1 caractère est codé sur 2 octets, alors qu'en ASCII, 1 caractère est codé sur 1 octet.
Ce type est utilisé par Automation pour la manipulation de chaînes de caractères. Il est défini dans les spécifications d'OLE 2.0 comme
typedef OLECHAR FAR* BSTR;
Avec un type comme celui-ci, on se demande souvent comment s'en servir dans son code C++

Voici deux fonctions utilisant l'api windows pour le transtypage en char*:

void BSTRtoASC (BSTR str, char * &strRet)
{
    if ( str != NULL )
   {
       unsigned long length = WideCharToMultiByte (CP_ACP, 0, str, SysStringLen(str),
                                            NULL, 0, NULL, NULL);
       strRet = new char[length];
        length = WideCharToMultiByte (CP_ACP, 0, str, SysStringLen(str), 
                           reinterpret_cast <char *>(strRet), length, NULL, NULL);
        strRet[length] = '\0';
    }
}

void ASCtoBSTR (char * str, BSTR * strRet)
{
    if ( str != NULL )
    {
        unsigned long length = strlen(str);
        int ResultLength = MultiByteToWideChar (CP_ACP,MB_PRECOMPOSED,
                           reinterpret_cast <char *>(str),length,NULL,0);
        *strRet = SysAllocStringLen( NULL, ResultLength);
        MultiByteToWideChar (CP_ACP,MB_PRECOMPOSED,
                           reinterpret_cast <char *>(str),length,*strRet,ResultLength);
    }
}
Si on utilise des CString MFC, voici une manière très simple de créer un BSTR:
CString strResult("un test de chaîne");
return strResult.AllocSysString();

Comment convertir une CString en int, double, long ?
Mise à jour le 22/01/2007[haut]
auteur : Farscape
La classe CString dispose de l'opérateur (const char *), de ce fait toutes les fonctions C disposant d'une signature const char * peuvent être utilisées.
Exemple de conversions d'une CString en différents types de données :
Cet exemple est adapté d'un code trouvé sur MSDN pour la fonction strtoul.

   char  *stopstring;
   double x;
   long   l;
   int    base;
   unsigned long ul;

   CString string="3.1415926This stopped it";

   x = strtod( string, &stopstring );
   TRACE( "string = %s\n",(const char *)string );
   TRACE("   strtod = %f\n", x );
   TRACE("   Stopped scan at: %s\n\n", stopstring );

   string = "-10110134932This stopped it";
   l = strtol( string, &stopstring, 10 );
   TRACE( "string = %s",(const char *)string );
   TRACE("   strtol = %ld", l );
   TRACE("   Stopped scan at: %s", stopstring );

   string = "10110134932";
   TRACE( "string = %s\n",(const char *)string );
   /* Convert string using base 2, 4, and 8: */
   for( base = 2; base <= 8; base *= 2 )
   {
      /* Convert the string: */
      ul = strtoul( string, &stopstring, base );
      TRACE( "   strtol = %ld (base %d)\n", ul, base );
      TRACE( "   Stopped scan at: %s\n", stopstring );
   }
résultats:

string = 3.1415926This stopped it
   strtod = 3.141593
   Stopped scan at: This stopped it

string = -10110134932This stopped it   strtol = -2147483647  
   Stopped scan at: This stopped itstring = 10110134932

   strtol = 45 (base 2)
   Stopped scan at: 34932
   strtol = 4423 (base 4)
   Stopped scan at: 4932
   strtol = 2134108 (base 8)
   Stopped scan at: 932
Autre possibilité utiliser la STL et la gestion des flux avec istringstream

#include <sstream>
template<typename T>
bool ConvertCString( const CString & Str, T & Dest )
{
    // créer un flux à partir de la chaîne donnée
    std::istringstream iss( static_cast<const char *>( Str) );
    // tenter la conversion vers Dest
    return iss >> Dest != 0;
}
CString str="25";
int nInt;
ConvertCString( str, nInt );
//ou
ConvertCString( "25", nInt );// fonctionne aussi ...
Cette dernière version est adaptée d'un post de la Faq C++


Comment convertir une CString vers une std::string et vice et versa ?
auteur : Farscape
Convertion d'une CString vers une std::string:

CString str("Bonjour");
std::string s((LPCTSTR)str);
Convertion d'une std::string vers une CString:

   std::string s("Bonjour");
   CString str(s.c_str());

Comment convertir des chaînes hexa en integer, inversement et plus largement comment changer la base d'une valeur dans une string ?
Créé le 04/04/2005[haut]
auteur : matazz

//***************************************************************************
// Change la base d'une valeur sous forme de chaîne.
//***************************************************************************
CString COutils::ChangeBase(CString Value, int BaseFrom, int BaseTo)
{
CString ValBaseChanged;

if (!( BaseFrom <2 || BaseFrom >36 || BaseTo <2 || BaseTo >36) )
{
char *StopScan= NULL;
char StrBaseOut[250];
intValIn= 0;
//Merci nico-pyright(c) 
ValIn = strtol(Value.GetBuffer(0), &StopScan, BaseFrom);
_itoa(ValIn, StrBaseOut, BaseTo);

ValBaseChanged = CString(StrBaseOut, strlen(StrBaseOut));
}
else
{ValBaseChanged = "Invalid Base Number";}
return ValBaseChanged;
}
Pour convertir une chaîne Hexa en integer il suffit juste d'utiliser strtol: voir Faq: faq Comment convertir une CString en int, double, long ?

char *StopScan= NULL;

intValIn= 0;
//Merci nico-pyright(c)
ValIn = strtol(Value.GetBuffer(0), &StopScan, BaseFrom);
remarque transformer un int en string hexa peut être fait grâce à la fonction format de CString :

CString StrHexa;
int Val = 125;

StrHexa.Format("%X",Val);
lien : faq Comment convertir une CString en int, double, long ?

Quel est le nombre de caractères maximum que peut contenir une CString ?
Créé le 04/04/2005[haut]
auteur : Farscape
On trouve la réponse dans le code de la classe CString avec la fonction AllocBuffer qui est utilisée pour allouer la mémoire nécessaire :

void CString::AllocBuffer(int nLen)
// always allocate one extra character for '\0' termination
// assumes [optimistically] that data length will equal allocation length
{
ASSERT(nLen >= 0);
ASSERT(nLen <= INT_MAX-1);    // max size (enough room for 1 extra)

if (nLen == 0)
Init();
else
{
CStringData* pData;
#ifndef _DEBUG
if (nLen <= 64)
{
pData = (CStringData*)_afxAlloc64.Alloc();
pData->nAllocLength = 64;
}
else if (nLen <= 128)
{
pData = (CStringData*)_afxAlloc128.Alloc();
pData->nAllocLength = 128;
}
else if (nLen <= 256)
{
pData = (CStringData*)_afxAlloc256.Alloc();
pData->nAllocLength = 256;
}
else if (nLen <= 512)
{
pData = (CStringData*)_afxAlloc512.Alloc();
pData->nAllocLength = 512;
}
else
#endif
{
pData = (CStringData*)
new BYTE[sizeof(CStringData) + (nLen+1)*sizeof(TCHAR)];
pData->nAllocLength = nLen;
}
pData->nRefs = 1;
pData->data()[nLen] = '\0';
pData->nDataLength = nLen;
m_pchData = pData->data();
}
}
La longueur maximale est donc égale à INT_MAX -1 avec INT_MAX = 2147483647 Soit 2 G° . Au passage on remarquera le traitement différent quand le bloc de mémoire à allouer est inférieur à 512 octets.
Noter aussi le traitement différent dans le cas du mode release et debug qui peut expliquer que certains bugs de mémoire n'apparaissent pas en release .


Comment faire une extraction dans une CString avec des séparateurs ?
Créé le 27/11/2005[haut]
auteur : Farscape
classiquement cette opération pourrait être réalisée avec la fonction C strtok.

Mais celle-ci à l'inconvénient de perturber la chaîne d'origine et de ne pas fonctionner dans certains cas :

CString str="aaa,bbb,ccc,,123";
   CString strTemp=str;
   char *pWord = strtok(strTemp.GetBuffer(0), ",");
   while( pWord != NULL )
   {
        // Work
        // ..................

         afxDump <<"\nWord:"<< "\"" <<pWord << "\""; 
        // Get Next Token
        pWord = strtok( NULL, "," );
   } 
   strTemp.ReleaseBuffer(); 
donnera successivement:
Word:"aaa"
Word:"bbb"
Word:"ccc"
Word:"123"
et saute la valeur vide ...

code proposé pour fonctionner avec des CString:

CString CStringTok(const char *szToken,const char *szDelimit,bool &rbEndParse)
{
   CString strOrg,str;
   static const char *pszOrg=NULL;

   ASSERT(szDelimit!=NULL);

   if(szToken)
   {
       pszOrg=szToken;
       rbEndParse=false;
   }
   if(!pszOrg)
   {
        rbEndParse=true;
        return "";
   }
   
   strOrg=pszOrg;
   int nPos=strOrg.Find(szDelimit);
   if(nPos!=-1)
   {
      str=strOrg.Left(nPos);
      pszOrg+=(nPos+strlen(szDelimit));
   }
   else
   {
      str=strOrg;
      pszOrg=NULL;      
   }
   return str;
} 

   CString strOrg="aaa,bbb,,ccc";

   bool bEndParse;
   CString strWord =CStringTok(strOrg,",",bEndParse);
   while(!bEndParse)
   {
      // Work
      // ..................
      afxDump <<"\nWord:"<< "\"" <<strWord << "\""; 
      // Get Next Token
      strWord = CStringTok(NULL,",",bEndParse);
   } 
donnera successivement:
Word:"aaa"
Word:"bbb"
Word:""
Word:"ccc"


Comment créer une chaîne de type BSTR ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
BSTR chaine = SysAllocString(L"Exemple de chaine");
On pourra utiliser SysStringLen pour faire une copie par exemple
BSTR chaine2 = SysAllocStringLen(chaine, SysStringLen(chaine));
Pour créer une chaîne depuis un char *, on pourra se reporter à l'utilisation de la fonction décrite ici faq Comment convertir un BSTR en chaîne ordinaire et vice-versa ?
char t1[] = "Exemple";
BSTR test1;
ASCtoBSTR(t1, &test1);

Comment concaténer 2 BSTR ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
BSTR chaine1 = SysAllocString(L"Exemple ");
BSTR chaine2 = SysAllocString(L"de chaine");
BSTR chaine3;
VarBstrCat(chaine1, chaine2, &chaine3); 

Comment libérer une chaîne de type BSTR ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
Il ne faudra pas oublier de libérer la mémoire avec SysFreeString
SysFreeString(chaineBstr);

Comment convertir un entier, un double, un float, etc, en chaîne de caractères ?
Créé le 22/01/2007[haut]
auteur : Farscape
La classe CString dispose d'une méthode Format qui prend en charge les conversions des types entier,double,float ,long etc .. de la même manière que la fonction printf ou sprintf du C,
Elle utilise donc les mêmes options.

Quelques exemples de conversions :

CString str;
str.Format(_T("Float arrondi 2 décimales: %.2f\n"), 12345.12345);
str.Format(_T("Float longueur 10 dont 2 décimales: %10.2f\n"), 12345.12345);
str.Format(_T("entier cadré a gauche : %.6d\n"), 35);
str.Format(_T("entier cadré avec zéro : %06d\n"), 35);
CString str2=_T("essai") ;
str.Format(_T("chaine :%s: \n"), static_cast<const char *>(str2));
char c='1';
str.Format(_T("char %c », c) ;
pour plus de détails: consulter la liste des spécifications de format


Comment convertir des chaînes de caractères en ANSI et en UNICODE avec les MFC ?
Créé le 22/01/2007[haut]
auteur : Gabrielly

{
        CStringW wstr = L"Chaine UNICODE";
        CStringA str(wstr);  // convertit en ANSI
        LPCSTR lpcstr = str;
        AfxMessageBox(lpcstr);
    }
    {
        CComBSTR bstr = L"Chaine UNICODE";
        CStringA str(bstr); // convertit en ANSI
        LPCSTR lpcstr = str;
        AfxMessageBox(lpcstr);
    }
    {
        CStringA str = "Chiane ANSI";
        CStringW wstr(str); // convertit en UNICODE
        LPCWSTR lpcwstr = wstr;
    }
    {
        CStringA str = "Chaine ANSI";
        CComBSTR bstr(str); // convertit en UNICODE
        BSTR b = bstr;
    }
    {
        GUID guid;
        ::CoCreateGuid(&guid);  // j'obtient un GUID
        CComBSTR bstrGuid(guid); // je convertit en UNICODE
        CStringA strGuid(bstrGuid);  // Je convertit en ANSI
        AfxMessageBox(strGuid);     // et j'affiche
        AfxMessageBox(CStringA(CComBSTR(guid))); // ou bien...
    }

Les constructeurs des classes CString et CComBSTR réalisent aisément des conversions pour nous.
Encore mieux CComBSTR convertit un GUID (Global Unique Identifier ou UUID= Universal Unique ID) en Unicode BSTR.


Comment convertir une CString ?
Créé le 17/09/2007[haut]
auteur : Farscape
En dehors des méthodes déjà présentées pour la conversion faq Comment convertir une CString en int, double, long ?

voici une autre méthode plus C++ de procéder :


#include <string>
#include <iostream>
#include <sstream>

template<typename T,typename S>
bool FromString( const S & Str, T & Dest )
{
#ifdef _UNICODE
    std::wistringstream iss( Str );
#else
    std::istringstream iss( Str );
#endif
    // tenter la conversion vers Dest
    return iss >> Dest != 0;
}
Utilisation:

int nInt ;
FromString(_T("10"), nInt ); // conversion en int.

double dDouble;
FromString( _T("3.14107"), dDouble ); // conversion en double

CString str=_T("1200");
#ifdef _UNICODE
    std::wstring strstl;
#else
    std::string strstl;
#endif

strstl=_T("1200");
int n=0;
FromString(str.GetString(),n);
n=0;
FromString(strstl,n);

Comment récupérer directement le contenu d'un contrôle dans un entier,double,long, etc.?
Créé le 17/09/2007[haut]
auteur : Farscape
les MFC comme l'api 32 permettent avec GetDlgItemInt la récupération du contenu d'un contrôle sous forme d'entier.
mais quid des autres types long,float,double ?
pour ces autres types il faudra attacher au contrôle une variable correspondante au type de donnée souhaité et appeler la méthode faq UpdateData(TRUE) pour disposer de la valeur.
le code qui suit permet de se passer de l'association d'une variable à un contrôle et donc de récupérer directement la valeur pour le type souhaité.



#include <sstream> 
#include <string> 
#include <iostream> 

template<typename T>
bool FromCtrl( const CWnd & Ctrl, T & Dest )
{
    CString Str;
    Ctrl.GetWindowText(Str);
#ifdef _UNICODE
    std::wistringstream iss( static_cast<LPCTSTR>( Str) );
#else
	std::istringstream iss( static_cast<LPCTSTR>( Str) );
#endif
    // tenter la conversion vers Dest
    return iss >> Dest != 0;
}
Utilisation:


double d;
FromCtrl(*GetDlgItem(IDC_EDITNOM),d);
if(d==10.0)
{
// traitement
}
// etc...

Comment affecter directement le contenu d'une variable de type int,long,double ... à un contrôle ?
Créé le 17/09/2007[haut]
auteur : Farscape
Les MFC comme l'api 32 permettent avec SetDlgItemInt l'affection d'un entier au contrôle.
mais quid des autres types long,float,double ?
pour ces autres types il faudra attacher au contrôle une variable correspondante au type de donnée traité et appeler la méthode faq UpdateData(FALSE) pour mettre à jour le contrôle.
le code qui suit permet de se passer de l'association d'une variable à un contrôle et donc d'affecter directement une valeur d'un type donné au contrôle.



#include <sstream>
#include <string>
#include <iomanip>
#include <iostream>

class FormatNum
{
public :
    FormatNum(){}
    template <typename T>
    FormatNum(const T&t)
    {
        operator <<(t);
    }
    template <typename T>
    FormatNum & operator << (const T& t)
    {        
        m_ss << t;
        return *this;
    }

public :
#ifdef _UNICODE
    std::wstringstream m_ss;
#else
    std::stringstream m_ss;
#endif
};

template<typename T>
void ToCtrl(CWnd & Ctrl,const T & Src,FormatNum &rFormat=FormatNum())
{
    rFormat << Src;

#ifdef _UNICODE
    std::wstring s=rFormat.m_ss.str();
#else
    std::string s=rFormat.m_ss.str();
#endif
    Ctrl.SetWindowText(s.c_str());
}
Utilisation:

// met 10.345 dans le contrôle.
ToCtrl(*GetDlgItem(IDC_EDITNUM),10.345);
// met 10.35 dans le contrôle.
ToCtrl(*GetDlgItem(IDC_EDITNUM),10.345,
            FormatNum()<<std::setprecision(4)); 
Le traitement se décompose en deux parties :
La fonction modèle ToCtrl permettant la transformation du type utilisateur et l'affectation de la chaîne au contrôle passée en argument.
Un objet fonction FormatNum optionnel qui permet le formatage du flux pour contrôler la conversion, l'enchainement des arguments, et qui fournit l'objet flux de conversion de la classe stringstream à la fonction modèle ToCtrl.
Voyons son utilisation dans les exemples qui suivent :
Dans le cas d'un double ou float si on veut maitriser la précision du nombre envoyé on pourra utiliser la fonction setprecision définie dans l'entête standard iomanip pour fixer le nombre de digits souhaités.
Vous pouvez bien-sûr utiliser les autres fonctions et compléter le flux
Exemples:
Contrôler la longueur de la chaîne créée, et spécifier un caractère de remplissage.

// donne 0000010.35
ToCtrl(*GetDlgItem(IDC_EDITNUM),10.345,
       FormatNum()<<std::setprecision(4)<<std::setfill(_TCHAR('0'))<<std::setw(10)); 
Cet exemple impose une précision de 4 digits, une chaîne de 10 caractères remplie avec des '0'.
Dans le même ordre d'idée on pourra fixer la base de conversion ...

// donne 0000000020
ToCtrl(*GetDlgItem(IDC_EDITNUM),32,
    FormatNum()<<std::setprecision(4)<<std::setfill(_TCHAR('0'))<<std::setw(10)<<setbase(16));
Enfin rajouter du texte devant la conversion :

// donne: Conversion Hexa: 0x0000000020
ToCtrl(*GetDlgItem(IDC_EDITNUM),
32,
FormatNum()<<_T("Conversion Hexa: 0x") <<std::setprecision(4)<<std::setfill(_TCHAR('0'))<<std::setw(10)<<setbase(16));
//ou
ToCtrl(*GetDlgItem(IDC_EDITNUM),
32,
FormatNum(_T("Conversion Hexa: 0x"))<<std::setprecision(4)<<std::setfill(_TCHAR('0'))<<std::setw(10)<<setbase(16)); 
Ou encore une syntaxe plus aérée:

FormatNum format;
format <<_T("Conversion Hexa: 0x") <<std::setprecision(4)<<std::setfill(_TCHAR('0'))<<std::setw(10)<<setbase(16);

ToCtrl(*GetDlgItem(IDC_EDITNUM),32,format); // donne: Conversion Hexa: 0x0000000020[FONT=monospace]
Vous noterez aussi l'utilisation optionnelle de la spécification du format de conversion (FormatNum).
On pourra compléter notre traitement par une fonction de conversion vers une CString ou string de la STL.

template<typename T,typename S>
void ToString(S & rstr,const T & Src,FormatNum &rFormat=FormatNum())
{    
    rFormat << Src;
#ifdef _UNICODE
    std::wstring s=rFormat.m_ss.str();
#else
    std::string s=rFormat.m_ss.str();
#endif
    rstr=s.c_str();
}
Utilisation :
CString str;
ToString(str,1200);
#ifdef _UNICODE
    std::wstring strstl;
#else
    std::string strstl;
#endif
ToString(strstl,1200);

Comment encoder une chaîne au format UTF8 ?
Créé le 07/07/2008[haut]
auteur : Farscape
UTF-8 (UCS transformation format 8 bits) permet de coder de l'Unicode sous une suite de 4 octets maximum.
Cette codification est par exemple utilisée dans le fichier document.xml au format OpenXml de Word 2007.
Les caractères dont le code ASCII est supérieur à 127 sont codés sur plusieurs octets.
Le code ci-dessus s'appuie sur la description donnée dans Wikipédia
Notes:
-Une chaîne au format UTF8 peut être contenue dans une CString multi bytes .
-j'ai implémenté la codification sur 4 octets mais l'exemple de Wikipédia avec le "?" ne semble pas correct dans ce cas puisque son code ASCII est égal à 63.
-ce code ne fonctionne pas directement avec Visual 6.0 à cause des CString: On ne dispose pas de CStringA et de CStringW...

//-------------------------------------------------------------------------
CStringA  UTF8EncodeString(const CStringA str)
{
   CStringW input(str);
   CStringA output;
   for(int i=0; i < input.GetLength(); i++)
   {
      // 0xxxxxxx
      if(input[i] < 0x80)
      {
        output+=input[i];         
      }       
      // C0          80    
      // 110xxxxx 10xxxxxx      
      else if((input[i] > 0x7F) && (input[i] < 0x800))
      {
         output+=static_cast<unsigned char>(0xC0 | (input[i] >> 6));
         output+=static_cast<unsigned char>(0x80 | (input[i] & 0x3F));                      
      }
      // E0       80       80
      // 1110xxxx 10xxxxxx 10xxxxxx
      else if(input[i] < 0x8000)
      {
        output+=static_cast<unsigned char>(0xE0 | (input[i] >> 12));         
        output+=static_cast<unsigned char>(0x80 | (input[i] >> 6 & 0x3F));         
        output+=static_cast<unsigned char>(0x80 | (input[i] & 0x3F));
      }
      else
      {  // F0      80       80       80
         //11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
        output+=static_cast<unsigned char>(0xF0 | (input[i] >> 12)>>6);
        output+=static_cast<unsigned char>(0x80 | (input[i] >> 12 & 0x3F));
        output+=static_cast<unsigned char>(0x80 | (input[i] >> 6 & 0x1F));
        output+=static_cast<unsigned char>(0x80 | (input[i] & 0x3F));
      }
   }
   return output;
} 
CStringA input,output;
input="é";
output=UTF8EncodeString(input);
TRACE("\n output é:%s",static_cast<const char *>(output));
input="?";
output=UTF8EncodeString(input);
TRACE("\n output ?:%s",static_cast<const char *>(output));

Comment décoder une chaîne au format UTF8 ?
Créé le 07/07/2008[haut]
auteur : Farscape
Pour plus d'informations voir la question faq Comment encoder une chaîne au format UTF8 ?

CStringA UTF8DecodeString(const CStringA input)
{   
   CStringW output;
   for(int i=0; i < input.GetLength();i++)
   {  
      // F0      80       80       80
      //11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
      if((input[i] & 0xFE) == 0xFE)
      {
           output+= static_cast<wchar_t>(((input[i] & 7 )<< 18) | ((input[i+1] & 0x3F) << 12) | ((input[i+2] & 0x3F) << 6) | (input[i+3] & 0x3F));
           i += 3;
      }
      else
      // E0       80       80
      // 1110xxxx 10xxxxxx 10xxxxxx
      if((input[i] & 0xE0) == 0xE0)
      {
         output+= static_cast<wchar_t>(((input[i] & 0x0F) << 12) | ((input[i+1] & 0x3F) << 6) | (input[i+2] & 0x3F));
         i += 2;
      }
      // C0       80
      // 110xxxxx 10xxxxxx
      else if((input[i] & 0xC0) == 0xC0)
      {
         output+= static_cast<wchar_t>(((input[i] & 0x1F) << 6) | (input[i+1] & 0x3F));
         i ++;
      }
      // 0xxxxxxx
      else if(input[i] < 0x80)   output+=input[i];           
   }
   return CStringA(output);
}

CStringA input,output;
input="é";
output=UTF8EncodeString(input);
TRACE("\n output é:%s",static_cast<const char *>(output));
output=UTF8DecodeString(output);
TRACE("\n output é:%s",static_cast<const char *>(output));
input="?";
output=UTF8EncodeString(input);
TRACE("\n output ?:%s",static_cast<const char *>(output));
output=UTF8DecodeString(output);
TRACE("\n output é:%s",static_cast<const char *>(output));
lien : faq Comment encoder une chaîne au format UTF8 ?

Comment convertir une chaîne UNICODE en Char * ?
Créé le 07/07/2008[haut]
auteur : Farscape
La conversion d'une chaîne UNICODE en chaîne de caractères est relativement aisée avec les MFC récentes (après visual 6.0).
En effet la classe CString permet de travailler sur les deux conventions UNICODE et Multi-Byte dans un même projet.
On aura alors :
La classe CString qui suivra le paramétrage du projet : UNICODE ou Multi-Byte
La classe CStringA pour travailler avec des chaînes de caractères Multi-Byte (char *) .
La classe CStringW pour travailler avec des chaînes Unicode.
Une conversion d'une chaîne UNICODE en Multi-Byte devient une chose aisée :

// réglage du projet en UNICODE
CString strWide=_T("chaine de caractères");
CStringA strA(strWide);

CString strWideDup(strA); // l'inverse
VERIFY(strWideDup==strWide);

char *sz=strA.GetBuffer(0);
L'exemple ci-dessus part d'une CString UNICODE et fournit une CString Multi-Byte et un pointeur sur char *.
et enfin fabrique une CString UNICODE à partir d'une CString Multi-Byte

Avec Visual 6.0:
CString travaille dans le mode réglé dans le projet.
Pour transformer une CString Unicode en chaîne de caractères il faudra utiliser l'api WideCharToMultiByte :

// réglage du projet en UNICODE
CString strWide=_T("chaine de caractères");
char *sz= new char [strWide.GetLength()+1] ;
WideCharToMultiByte( CP_ACP, 0, strWide, -1, sz, strWide.GetLength()+1, NULL, NULL );
//......
delete[] sz;
Pour transformer une chaîne de caractères en chaîne Unicode on utilisera MultiByteToWideChar

// réglage du projet en UNICODE
CString strWide=_T("chaine de caractères");
char *sz= new char [strWide.GetLength()+1] ;
WideCharToMultiByte( CP_ACP, 0, strWide, -1, sz, strWide.GetLength()+1, NULL, NULL );
  
int nSize=strlen(sz)+1;
TCHAR *wsz= new TCHAR[nSize];
MultiByteToWideChar( CP_ACP, 0, sz,nSize,wsz,nSize);
CString strWideDup=wsz;
  
VERIFY(strWideDup==strWide);
//......
delete[] wsz;
delete[] sz;


Consultez les autres F.A.Q.


Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2004 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.