LINUX.ORG.RU

C++ может кому нужны функции raw string <-> wstring (взависимости от locale)


0

0

Привет!
Может кому нужны фунции raw string <--> wstring взависимости от locale.
Используя только стандартную библиотеку С++.

wstring - это всегда UCS-4. Один символ 4 байта.
string - набор байтов. причем этот набор байтов интерпретируется в зависимости от указанной локали. Так один символ может например занимать от 1ного байта до 6ти байт (все зависит от локали).

Легко можно конвертировать строки из/в различных кодировок.

/**
* Function: zero_state
* Purpose: set zero state for multi myte state
* Arguments:
* input: mbstate_t & - what state set to zero
* Return: nothing
*/

static
void zero_state(mbstate_t& state)
{
std::memset(&state, 0, sizeof(std::mbstate_t));
}

/**
* Function: wstring2string
* Purpose: convert message from wide char representation to raw byte string,
* considering to specified locale
* Arguments:
* input: const wstring & - input string, where each character in wchar_t
* input: const string & - where to put output string, in raw mode
* input: locale - locale set up coverting rules (for example: from UCS-4
* to ru_RU.UTF-8, or to ru_RU.KOI8-R)
* Return: bool - succes of result
*/
bool wstring2string(const wstring & aInStr, string & aOutStr, locale aLoc = locale::classic())
{
typedef codecvt<wchar_t, char, mbstate_t> TCodeCvt;
const TCodeCvt * cv = &use_facet<TCodeCvt>(aLoc);

wstring::size_type in_len = aInStr.size();
const wchar_t * in_start = aInStr.c_str();
const wchar_t * in_end = in_start + in_len;
int mult = cv->max_length();
cout << "MULT: " << mult << endl;
char out_start [in_len * mult];
char * out_end = out_start + in_len * mult;
mbstate_t state;
zero_state(state);

const wchar_t * from_next = 0; // unused
char * to_next = 0;
bool result = (cv->out(state, in_start, in_end, from_next, out_start, out_end, to_next)
== TCodeCvt::ok);

if(result)
{
string::size_type out_len = to_next - out_start;
aOutStr.assign(out_start, out_len);
}

return result;
}


/**
* Function: string2wstring
* Purpose: convert message from raw representation to wide char string,
* considering to specified locale ( exmple from ru_RU.UTF-8 to UCS-4, or from
* ru_RU.KOI8-R to UCS-4)
* Arguments:
* input: const string & - input string, where each character can be in
* one byte or in several bytes ( it depends from locale )
* input: const wstring & - where to put output string, each character
* have wchar_t type
* input: locale - locale set up coverting rules
* Return: bool - succes of result
*/bool string2wstring(const string & aInStr, wstring & aOutStr, locale aLoc = locale::classic())
{
typedef codecvt<wchar_t, char, mbstate_t> TCodeCvt;
const TCodeCvt * cv = &use_facet<TCodeCvt>(aLoc);

string::size_type in_len = aInStr.size();
const char * in_start = aInStr.c_str();
const char * in_end = in_start + in_len;
wchar_t out_start [in_len];
wchar_t * out_end = out_start + in_len;
mbstate_t state;
zero_state(state);

const char * from_next = 0; // unused
wchar_t * to_next = 0;
bool result = (cv->in(state, in_start, in_end, from_next, out_start, out_end, to_next)
== TCodeCvt::ok);

if(result)
{
wstring::size_type out_len = to_next - out_start;
aOutStr.assign(out_start, out_len);
}

return result;
}

anonymous
Ответ на: комментарий от Sheph

wchar бывает как двух- так и четырехбайтовым на разных системах. У gcc, к примеру, есть переключатель.

anonymous
()
Ответ на: комментарий от Sheph

для mbstowcs необходимо глобально установить локаль. что может помешать выполнению программы. это C-шная функция

anonymous
()

Откройте для себя glib (не путать с glibc, или iconv он входит в glibc)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.