Здравствуйте, INsideR, Вы писали:
INR>Как преобразовать строку char * в её эквивалент на Unicode, не используя #define _UNICODE. И в каком типе данных можно хранить unicode строку? Есть ли классы для работы с Unicode строками, типа CString?
Насчет классов — std::wstring.
Насчет преобразования, см.
ansi_to_unicode и
unicode_to_ansi
////////////////////////////////////////////////////////////////////////////////
//Implementation of conversion utility from <t_char.h>
// Dmitry Kovalenko. 19 august,2002.
#ifndef _t_char_converter_CC_
#define _t_char_converter_CC_
#include <structure/t_memory.h>
namespace structure{
////////////////////////////////////////////////////////////////////////////////
//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>
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();
#ifndef NDEBUG
if(str_len!=-1)
CHECK_READ_PTR((LPSTR)str,sizeof(CHAR)*str_len);
#endif
//если str_len==-1, то WCTMB учитывает завершающий нулевой символ
int wlen=::MultiByteToWideChar(CodePage,0,str,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);//вернем не только завершающий символ
//резервируем место под все символы (включая и терминальный)
result.resize(wlen);
::MultiByteToWideChar(CodePage,0,str,str_len,result.begin(),wlen);
//удаляем терминальный UNICODE-символ
return result.erase(result.size()-1,1);
}//t_ansi_to_unicode::convert (result...)
template<class unicode_string>
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 wstring ansi_to_unicode(LPCSTR t,size_t n,bool* error,UINT CodePage)
{
typedef t_ansi_to_unicode<wstring> convertor_type;
return convertor_type::convert(t,n,error,CodePage);
}//ansi_to_unicode
inline wstring ansi_to_unicode(const string& t,bool* error,UINT CodePage)
{
typedef t_ansi_to_unicode<wstring> convertor_type;
return convertor_type::convert(t.c_str(),t.size(),error,CodePage);
}//ansi_to_unicode
inline wstring& ansi_to_unicode(wstring& result,LPCSTR t,size_t n,bool* error,UINT CodePage)
{
typedef t_ansi_to_unicode<wstring> convertor_type;
return convertor_type::convert(result,t,n,error,CodePage);
}//ansi_to_unicode
inline wstring& ansi_to_unicode(wstring& result,const string& t,bool* error,UINT CodePage)
{
typedef t_ansi_to_unicode<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>
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();
#ifndef NDEBUG
if(wstr_len!=-1)
CHECK_READ_PTR((LPWSTR)wstr,sizeof(WCHAR)*wstr_len);
#endif
//если wstr_len==-1, то WCTMB учитывает завершающий нулевой символ
int alen=::WideCharToMultiByte(CodePage,0,wstr,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);//вернем не только завершающий символ
//резервируем место под все символы (включая и терминальный)
result.resize(alen);
::WideCharToMultiByte(CodePage,0,wstr,wstr_len,result.begin(),alen,NULL,NULL);
//исключаем терминальный символ
//TODO: Уверенность относительно одного байта?
return result.erase(result.size()-1,1);
}//t_unicode_to_ansi::convert
template<class ansi_string>
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 string unicode_to_ansi(LPCWSTR t,size_t n,bool* error,UINT CodePage)
{
typedef t_unicode_to_ansi<string> convertor_type;
return convertor_type::convert(t,n,error,CodePage);
}
inline string unicode_to_ansi(const wstring& t,bool* error,UINT CodePage)
{
typedef t_unicode_to_ansi<string> convertor_type;
return convertor_type::convert(t.c_str(),t.size(),error,CodePage);
}
inline string& unicode_to_ansi(string& result,LPCWSTR t,size_t n,bool* error,UINT CodePage)
{
typedef t_unicode_to_ansi<string> convertor_type;
return convertor_type::convert(result,t,n,error,CodePage);
}
inline string& unicode_to_ansi(string& result,const wstring& t,bool* error,UINT CodePage)
{
typedef t_unicode_to_ansi<string> convertor_type;
return convertor_type::convert(result,t.c_str(),t.size(),error,CodePage);
}
////////////////////////////////////////////////////////////////////////////////
};//namespace structure
#endif
-- Пользователи не приняли программу. Всех пришлось уничтожить. --