Как сконвертировать Std::wstring в Char* ?

Тема в разделе "Общие вопросы по С и С++", создана пользователем Danechka, 24 июл 2007.

Статус темы:
Закрыта.
  1. Danechka

    Danechka Гость

    Как сконвертировать std::wstring в char* ?
    Желательно с конкретным примером, если можно....
     
  2. Kmet

    Kmet Well-Known Member

    Регистрация:
    25 май 2006
    Сообщения:
    1.017
    Симпатии:
    1
    не совсем корректный вопрос. общее решение для всех кодировок написать проблематично.
    что то более менее общее ниже, извиняюсь за такую простыню, но было лень вырезать
    Код (Text):
    #ifndef _t_char_converter_CC_
    #define _t_char_converter_CC_


    #include <assert.h>
    #include "kmtcmn.h"



    namespace kmt{
    namespace conv{
    ////////////////////////////////////////////////////////////////////////////////
    //containing

    template<class unicode_string>
    struct t_ansi_to_unicode;

    template<class ansi_string>
    struct t_unicode_to_ansi;

    ////////////////////////////////////////////////////////////////////////////////
    //struct t_ansi_to_unicode

    template<class unicode_string>
    struct t_ansi_to_unicode
    {
    typedef unicode_string                                  string_type;
    typedef typename string_type::value_type                 char_type;
    //typedef t_void_allocator                               allocator_type;
    //typedef t_typed_simple_buffer<char_type,allocator_type>  buffer_type;

    //convert 't' to 'result' and return 'result'
    static string_type& convert(string_type& result,LPCSTR t,size_t n=-1,bool* error=NULL,UINT CodePage=CP_ACP);

    static string_type convert(LPCSTR t,size_t n=-1,bool* error=NULL,UINT CodePage=CP_ACP);
    };//struct t_ansi_to_unicode

    ////////////////////////////////////////////////////////////////////////////////
    //template struct t_ansi_to_unicode

    template<class unicode_string>
    typename t_ansi_to_unicode<unicode_string>::string_type&
    t_ansi_to_unicode<unicode_string>::convert(string_type& result,
    LPCSTR str,size_t str_len,bool* error,UINT CodePage)
    {
    if(error)
    *error=false;

    if(str==NULL || str_len==0)
    return result.erase();


    //åñëè str_len==-1, òî WCTMB ó÷èòûâàåò çàâåðøàþùèé íóëåâîé ñèìâîë
    int wlen=::MultiByteToWideChar(CodePage,0,str, (int)str_len,NULL,0);

    assert(wlen>=0);
    if(wlen==0 || (wlen==1 && str_len==-1))//error èëè str==""
    {
    if(error)
    *error=::GetLastError()?true:false;

    return result.erase();
    }

    if(str_len!=-1)
    wlen+=1;//ó÷èòûâàåì çàâåðøàþùèé UNICODE-ñèìâîë

    assert(wlen>1);//âåðíåì íå òîëüêî çàâåðøàþùèé ñèìâîë

    //ðåçåðâèðóåì ìåñòî ïîä âñå ñèìâîëû (âêëþ÷àÿ è òåðìèíàëüíûé)
    string_type::value_type *pbuf= new string_type::value_type[wlen];

    int rw=::MultiByteToWideChar(CodePage,0,str,(int)str_len,pbuf,wlen);
    result.erase();
    result.append(pbuf, pbuf+rw);
    delete[] pbuf;

    return result;//.erase(result.size()-1,1);
    }//t_ansi_to_unicode::convert (result...)

    template<class unicode_string>
    typename t_ansi_to_unicode<unicode_string>::string_type
    t_ansi_to_unicode<unicode_string>::convert(LPCSTR str,size_t str_len,bool* error,UINT CodePage)
    {
    string_type result;

    return convert(result,str,str_len,error,CodePage);
    }//t_ansi_to_unicode::convert

    ////////////////////////////////////////////////////////////////////////////////
    //inline implementation

    inline std::wstring ansi_to_unicode(LPCSTR t,size_t n,bool* error,UINT CodePage)
    {
    typedef t_ansi_to_unicode<std::wstring> convertor_type;

    return convertor_type::convert(t,n,error,CodePage);
    }//ansi_to_unicode

    inline std::wstring ansi_to_unicode(const std::string& t,bool* error,UINT CodePage)
    {
    typedef t_ansi_to_unicode<std::wstring> convertor_type;

    return convertor_type::convert(t.c_str(),t.size(),error,CodePage);
    }//ansi_to_unicode

    inline std::wstring& ansi_to_unicode(std::wstring& result,LPCSTR t,size_t n,bool* error,UINT CodePage)
    {
    typedef t_ansi_to_unicode<std::wstring> convertor_type;

    return convertor_type::convert(result,t,n,error,CodePage);
    }//ansi_to_unicode

    inline std::wstring& ansi_to_unicode(std::wstring& result,const std::string& t,bool* error,UINT CodePage)
    {
    typedef t_ansi_to_unicode<std::wstring> convertor_type;

    return convertor_type::convert(result,t.c_str(),t.size(),error,CodePage);
    }

    ////////////////////////////////////////////////////////////////////////////////
    //struct t_unicode_to_ansi

    template<class ansi_string>
    struct t_unicode_to_ansi
    {
    typedef ansi_string                                   string_type;
    typedef typename string_type::value_type                 char_type;
    //typedef t_void_allocator                               allocator_type;
    //typedef t_typed_simple_buffer<char_type,allocator_type>  buffer_type;

    //convert 't' to 'result' and resurn 'result'
    static string_type& convert(string_type& result,LPCWSTR t,size_t n=-1,bool* error=NULL,UINT CodePage=CP_ACP);

    static string_type convert(LPCWSTR t,size_t n=-1,bool* error=NULL,UINT CodePage=CP_ACP);
    };//struct t_unicode_to_ansi

    ////////////////////////////////////////////////////////////////////////////////
    //template struct t_unicode_to_ansi

    template<class ansi_string>
    typename t_unicode_to_ansi<ansi_string>::string_type&
    t_unicode_to_ansi<ansi_string>::convert(string_type& result,
    LPCWSTR wstr,size_t wstr_len,bool* error,UINT CodePage)
    {
    if(error)
    *error=false;

    if(wstr==NULL || wstr_len==0)
    return result.erase();


    //åñëè wstr_len==-1, òî WCTMB ó÷èòûâàåò çàâåðøàþùèé íóëåâîé ñèìâîë
    int alen=::WideCharToMultiByte(CodePage,0,wstr,(int)wstr_len,NULL,0,NULL,NULL);

    assert(alen>=0);
    if(alen==0 || (alen==1 && wstr_len==-1))//error èëè wstr==L""
    {
    if(error)
    *error=GetLastError()?true:false;

    return result.erase();
    }

    //TODO: Çäåñü ïðåäïîëàãàåòñÿ, ÷òî äëÿ âñåõ ANSI êîäèðîâîê òåðìèíàëüíûé ñèìâîë
    //   çàíèìàåò 1 áàéò
    if(wstr_len!=-1)
    alen+=1;//ó÷èòûâàåì çàâåðøàþùèé ñèìâîë

    assert(alen>1);//âåðíåì íå òîëüêî çàâåðøàþùèé ñèìâîë

    //ðåçåðâèðóåì ìåñòî ïîä âñå ñèìâîëû (âêëþ÷àÿ è òåðìèíàëüíûé)
    string_type::value_type *pbuf= new string_type::value_type[alen];

    int rw=::WideCharToMultiByte(CodePage,0,wstr,(int)wstr_len,pbuf,alen,NULL,NULL);
    result.erase();
    result.append(pbuf, pbuf+rw);

    delete[] pbuf;

    //èñêëþ÷àåì òåðìèíàëüíûé ñèìâîë
    //TODO: Óâåðåííîñòü îòíîñèòåëüíî îäíîãî áàéòà?
    return result;//.erase(result.size()-1,1);
    }//t_unicode_to_ansi::convert

    template<class ansi_string>
    typename t_unicode_to_ansi<ansi_string>::string_type
    t_unicode_to_ansi<ansi_string>::convert(LPCWSTR wstr,size_t wstr_len,bool* error,UINT CodePage)
    {
    string_type result;

    return convert(result,wstr,wstr_len,error,CodePage);
    }//t_unicode_to_ansi::convert

    //inline implementation --------------------------------------------------
    inline std::string unicode_to_ansi(LPCWSTR t,size_t n,bool* error=NULL,UINT CodePage=CP_ACP)
    {
    typedef t_unicode_to_ansi<std::string> convertor_type;

    return convertor_type::convert(t,n,error,CodePage);
    }

    inline std::string unicode_to_ansi(const std::wstring& t,bool* error=NULL,UINT CodePage=CP_ACP)
    {
    typedef t_unicode_to_ansi<std::string> convertor_type;

    return convertor_type::convert(t.c_str(),t.size(),error,CodePage);
    }

    inline std::string& unicode_to_ansi(std::string& result,LPCWSTR t,size_t n,bool* error=NULL,UINT CodePage=CP_ACP)
    {
    typedef t_unicode_to_ansi<std::string> convertor_type;

    return convertor_type::convert(result,t,n,error,CodePage);
    }

    inline std::string& unicode_to_ansi(std::string& result,const std::wstring& t,bool* error=NULL ,UINT CodePage=CP_ACP)
    {
    typedef t_unicode_to_ansi<std::string> convertor_type;

    return convertor_type::convert(result,t.c_str(),t.size(),error,CodePage);
    }

    inline std::string tchar2ansi(kmt::unicode::tstring t,bool* error=NULL ,UINT CodePage=CP_ACP)
    {
    #ifndef _UNICODE
    return unicode_to_ansi(t,error, CodePage);
    #else
    return t;
    #endif //_UNICODE
    }

    ////////////////////////////////////////////////////////////////////////////////
    };//namespace conv
    };//namespace kmt
    #endif
     
  3. mms

    mms Гость

    Зачем такие усложнения? :D

    Топикстартеру, смотри функцию WideCharToMultiByte, и используй её для своих конкретных нужд, выльется это в пару другую строк, но не в несколько страниц :D.

    Хотя если конвертация используется часто, стоит присмотреться к методам приведенным выше ...
     
  4. Danechka

    Danechka Гость

    Всем спасибо!
    Проблему решил при помощи wcstombs.
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей