Как конвертировать wstring в строку?

204

Вопрос в том, как преобразовать строку в строку?

У меня есть следующий пример:

#include <string>
#include <iostream>

int main()
{
    std::wstring ws = L"Hello";
    std::string s( ws.begin(), ws.end() );

  //std::cout <<"std::string =     "<<s<<std::endl;
    std::wcout<<"std::wstring =    "<<ws<<std::endl;
    std::cout <<"std::string =     "<<s<<std::endl;
}

вывод с закомментированной строкой:

std::string =     Hello
std::wstring =    Hello
std::string =     Hello

но без только:

std::wstring =    Hello

Что-то не так в примере? Могу ли я сделать преобразование, как указано выше?

РЕДАКТИРОВАТЬ

Новый пример (с учетом некоторых ответов)

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

int main()
{
    setlocale(LC_CTYPE, "");

    const std::wstring ws = L"Hello";
    const std::string s( ws.begin(), ws.end() );

    std::cout<<"std::string =     "<<s<<std::endl;
    std::wcout<<"std::wstring =    "<<ws<<std::endl;

    std::stringstream ss;
    ss << ws.c_str();
    std::cout<<"std::stringstream =     "<<ss.str()<<std::endl;
}

Выход:

std::string =     Hello
std::wstring =    Hello
std::stringstream =     0x860283c

поэтому поток строки нельзя использовать для преобразования wstring в строку.

BЈовић
источник
4
Как вы можете задать этот вопрос, не указав также кодировки?
Дэвид Хеффернан
5
@tenfour: зачем std::wstringвообще использовать ? stackoverflow.com/questions/1049947/...
кафеля
11
@dalle Если у вас есть данные , которые уже закодированные с UTF-16, или не считается вредным UTF-16 несколько спорно. И что бы это ни стоило, я не думаю, что любая форма трансформации вредна; что вредно, так это то, что люди думают, что понимают Unicode, хотя на самом деле это не так.
Дэвид Хеффернан
2
Это должно быть кроссплатформенное решение?
ali_bahoo
2
Стандарт @dalle c ++ никоим образом не упоминает utf (utf-8 или utf-16). Получил ссылку, где говорится, что utf-16 не может быть закодирован с помощью wstring?
BЈовић

Ответы:

31

Вот разработанное решение, основанное на других предложениях:

#include <string>
#include <iostream>
#include <clocale>
#include <locale>
#include <vector>

int main() {
  std::setlocale(LC_ALL, "");
  const std::wstring ws = L"ħëłlö";
  const std::locale locale("");
  typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;
  const converter_type& converter = std::use_facet<converter_type>(locale);
  std::vector<char> to(ws.length() * converter.max_length());
  std::mbstate_t state;
  const wchar_t* from_next;
  char* to_next;
  const converter_type::result result = converter.out(state, ws.data(), ws.data() + ws.length(), from_next, &to[0], &to[0] + to.size(), to_next);
  if (result == converter_type::ok or result == converter_type::noconv) {
    const std::string s(&to[0], to_next);
    std::cout <<"std::string =     "<<s<<std::endl;
  }
}

Обычно это работает для Linux, но создает проблемы в Windows.

Philipp
источник
@Phillip: какая часть кода зависит от локали c? это std::setlocale(LC_ALL, "");действительно необходимо?
Смерлин
2
Использование std::wcout.imbue(locale)должно делать работу так же хорошо, и оно имеет то преимущество, что оно не меняет глобального состояния.
Смерлин
32
В std::wstring_convertC ++ 11 много шума.
Cubbi
7
@ Филипп, что ты имеешь в виду "создаст проблемы в Windows"? Какие проблемы?
Гили
1
Приведенный выше код дает (как скопировано) дает мне *** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***на Linux 64-бит (gcc 4.7.3). Кто-нибудь еще испытывает это?
Hogliux
312

Как отметил Cubbi в одном из комментариев, std::wstring_convert(C ++ 11) предлагает простое и удобное решение (вам нужно #include <locale>и <codecvt>):

std::wstring string_to_convert;

//setup converter
using convert_type = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_type, wchar_t> converter;

//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
std::string converted_str = converter.to_bytes( string_to_convert );

Я использовал комбинацию wcstombsи утомительное распределение / освобождение памяти, прежде чем я столкнулся с этим.

http://en.cppreference.com/w/cpp/locale/wstring_convert

обновление (2013.11.28)

Один лайнер можно сформулировать так (спасибо, Гусс, за ваш комментарий):

std::wstring str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("some string");

Функции оболочки могут быть сформулированы так: (Спасибо, ArmanSchwarz за комментарий)

std::wstring s2ws(const std::string& str)
{
    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.from_bytes(str);
}

std::string ws2s(const std::wstring& wstr)
{
    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.to_bytes(wstr);
}

Примечание: есть некоторые споры о том string/ wstringдолжно быть переданы и функции как ссылка или как литералы (из - за C ++ 11 и компилятор обновлений). Я оставлю решение человеку, осуществляющему, но это стоит знать.

Примечание: я использую std::codecvt_utf8в приведенном выше коде, но если вы не используете UTF-8, вам нужно изменить его на соответствующую кодировку:

http://en.cppreference.com/w/cpp/header/codecvt

dk123
источник
25
Пожалуйста, +1 : это официальный C ++ стандартный способ преобразования строк. Вы также можете использовать from_bytes для преобразования другим способом. Поскольку я лично люблю однострочники, вот моя версия:std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
Guss
7
Похоже, что en.cppreference.com/w/cpp/header/codecvt недоступен с g ++ 4.8.2. Два метода s2ws и ws2s в настоящее время не работают под linux
Begui
5
Похоже, это устарело ( stackoverflow.com/a/42946556/211176 ). Мой компилятор выдает ошибки, когда я пытаюсь запустить этот код
adam_0
5
Для всех, кто беспокоится о C ++ 17 и дальнейшей совместимости (из-за устаревания), смотрите: stackoverflow.com/a/18597384/6205379
Timo
128

Решение от: http://forums.devshed.com/c-programming-42/wstring-to-string-444006.html

std::wstring wide( L"Wide" ); 
std::string str( wide.begin(), wide.end() );

// Will print no problemo!
std::cout << str << std::endl;

Помните, что здесь не происходит никакого преобразования набора символов. Что это делает просто присвоить каждую итерацию wchar_tк char- усечению преобразования. Он использует std :: string c'tor :

template< class InputIt >
basic_string( InputIt first, InputIt last,
              const Allocator& alloc = Allocator() );

Как указано в комментариях:

значения 0-127 идентичны практически в каждой кодировке, поэтому усечение значений, которые меньше 127, приводит к одному и тому же тексту. Введите китайский иероглиф, и вы увидите провал.

-

значения 128-255 кодовой страницы Windows 1252 (по умолчанию Windows English) и значения 128-255 юникода в основном одинаковы, поэтому, если вы используете кодовую страницу, большинство этих символов должны быть усечены до правильных значений. (Я полностью ожидал, что и õ будет работать, я знаю, что наш код на работе полагается на это для é, который я скоро исправлю)

И обратите внимание, что кодовые точки в диапазоне 0x80 - 0x9Fв Win1252 не будут работать. Это включает в себя , œ, ž, Ÿ, ...

namar0x0309
источник
2
Как ни странно, это работает в Visual Studio 10. Что происходит? Это должно привести к усечению назначения от wchar_t до char для всех элементов исходной строки.
Педро Ламанао
6
... когда речь идет о любых нелатинских символах.
JavaRunner
8
@ PedroLamarão: значения 0-127 идентичны практически в каждой кодировке, поэтому усечение значений, которые меньше 127, приводит к одному и тому же тексту. Введите китайский иероглиф, и вы увидите провал.
Mooing Duck
3
@ PedroLamarão: значения 128-255 кодовой страницы Windows 1252 (по умолчанию для английского языка в Windows) и значения Unicode 128-255 в основном одинаковы, поэтому, если вы используете кодовую страницу, большинство этих символов должны быть усечены до правильного ценности. (Я полностью ожидал, что õ и õ будут работать, я знаю, что наш код на работе полагается на это для é, который я скоро исправлю)
Mooing Duck
2
Это прекрасно работает. MSVS 2015 и MSVS 2017 и MINGW / g ++ и clang ++. Легит ++ 1.
Никос
11

Вместо того, чтобы включать локаль и все эти причудливые вещи, если вы знаете, что для FACT ваша строка конвертируема, просто сделайте это:

#include <iostream>
#include <string>

using namespace std;

int main()
{
  wstring w(L"bla");
  string result;
  for(char x : w)
    result += x;

  cout << result << '\n';
}

Живой пример здесь

rubenvb
источник
2
+1, потому что это простое решение, которое работает для некоторых сценариев (для свободного определения «работ», я мог бы добавить).
ворон
2
Практически то же самое, что и решение namar0x0309, которое намного элегантнее ИМХО. Но это только я.
onitake
Я увеличил ваш код, чтобы он работал с минимальными изменениями ;-)
rubenvb
9
-1 Если у вас есть wstring, скорее всего, вы имеете дело с многобайтовыми символами. Если бы вы могли знать, что строка тривиально конвертируема, вы бы не стали обрабатывать wstring. Скорее всего, вы имеете дело с другой библиотекой, которая ожидает от вас правильной обработки wstring. Усечение wchars - это просто попрошайничество над трудной для отслеживания ошибки позже. Кроме того, вы должны использовать «string result (w.begin (), w.end ());» если вы собираетесь это сделать, чтобы избежать цикла, который может вызвать много перераспределений.
Киан
7

Я полагаю, что официальный путь все еще состоит в том, чтобы идти codecvtгранями (вам нужен какой-то перевод с учетом местных особенностей ), как в

resultCode = use_facet<codecvt<char, wchar_t, ConversionState> >(locale).
  in(stateVar, scratchbuffer, scratchbufferEnd, from, to, toLimit, curPtr);

или что-то в этом роде, у меня нет рабочего кода. Но я не уверен, сколько людей в наши дни используют этот механизм, а сколько просто запрашивают указатели на память и позволяют ICU или какой-либо другой библиотеке обрабатывать мрачные детали.

Кристофер Кройциг
источник
7

Есть две проблемы с кодом:

  1. Преобразование в const std::string s( ws.begin(), ws.end() );не требуется для правильного сопоставления широких символов с их узким аналогом. Скорее всего, каждый широкий символ будет просто соответствовать типу char.
    Решение этой проблемы уже дано в ответе Кемом и включает narrowфункцию ctypeаспекта локали .

  2. Вы пишете вывод для обеих std::coutи std::wcoutв одной и той же программе. Оба coutи wcoutсвязаны с одним и тем же потоком ( stdout), и результаты использования одного и того же потока как байтового потока (как это coutделается), так и широкого ориентированного потока (как это wcoutделается) не определены.
    Лучший вариант - избегать смешивания узких и широких выходных данных с одним и тем же (базовым) потоком. Для stdout/ cout/ wcoutвы можете попробовать изменить ориентацию stdoutпри переключении между широким и узким выходом (или наоборот):

    #include <iostream>
    #include <stdio.h>
    #include <wchar.h>
    
    int main() {
        std::cout << "narrow" << std::endl;
        fwide(stdout, 1); // switch to wide
        std::wcout << L"wide" << std::endl;
        fwide(stdout, -1); // switch to narrow
        std::cout << "narrow" << std::endl;
        fwide(stdout, 1); // switch to wide
        std::wcout << L"wide" << std::endl;
    }
Барт ван Инген Шенау
источник
Да, это решает проблему с использованием cout и wcout.
BЈовић
7

Кодировка по умолчанию:

  • Windows UTF-16.
  • Linux UTF-8.
  • MacOS UTF-8.

Этот код имеет две формы для преобразования std :: string в std :: wstring и std :: wstring в std :: string. Если вы отрицаете # если определен WIN32, вы получите тот же результат.

1. std :: string to std :: wstring

MultiByteToWideChar WinAPI

_mbstowcs_s_l

#if defined WIN32
#include <windows.h>
#endif

std::wstring StringToWideString(std::string str)
{
    if (str.empty())
    {
        return std::wstring();
    }
    size_t len = str.length() + 1;
    std::wstring ret = std::wstring(len, 0);
#if defined WIN32
    int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, &str[0], str.size(), &ret[0], len);
    ret.resize(size);
#else
    size_t size = 0;
    _locale_t lc = _create_locale(LC_ALL, "en_US.UTF-8");
    errno_t retval = _mbstowcs_s_l(&size, &ret[0], len, &str[0], _TRUNCATE, lc);
    _free_locale(lc);
    ret.resize(size - 1);
#endif
    return ret;
}

2. std :: wstring в std :: string

WideCharToMultiByte WinAPI

_wcstombs_s_l

std::string WidestringToString(std::wstring wstr)
{
    if (wstr.empty())
    {
        return std::string();
    }
#if defined WIN32
    int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
    std::string ret = std::string(size, 0);
    WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &wstr[0], wstr.size(), &ret[0], size, NULL, NULL);
#else
    size_t size = 0;
    _locale_t lc = _create_locale(LC_ALL, "en_US.UTF-8");
    errno_t err = _wcstombs_s_l(&size, NULL, 0, &wstr[0], _TRUNCATE, lc);
    std::string ret = std::string(size, 0);
    err = _wcstombs_s_l(&size, &ret[0], size, &wstr[0], _TRUNCATE, lc);
    _free_locale(lc);
    ret.resize(size - 1);
#endif
    return ret;
}

3. На windows нужно распечатать юникод, используя WinAPI.

WriteConsole

#if defined _WIN32
    void WriteLineUnicode(std::string s)
    {
        std::wstring unicode = StringToWideString(s);
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), unicode.length(), NULL, NULL);
        std::cout << std::endl;
    }

    void WriteUnicode(std::string s)
    {
        std::wstring unicode = StringToWideString(s);
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), unicode.length(), NULL, NULL);
    }

    void WriteLineUnicode(std::wstring ws)
    {
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), ws.c_str(), ws.length(), NULL, NULL);
        std::cout << std::endl;
    }

    void WriteUnicode(std::wstring ws)
    {
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), ws.c_str(), ws.length(), NULL, NULL);
    }

4. По основной программе.

#if defined _WIN32
int wmain(int argc, WCHAR ** args)
#else
int main(int argc, CHAR ** args)
#endif
{
    std::string source = u8"ÜüΩωЙ你月曜日\na🐕èéøÞǽлљΣæča🐕🐕";
    std::wstring wsource = L"ÜüΩωЙ你月曜日\na🐕èéøÞǽлљΣæča🐕🐕";

    WriteLineUnicode(L"@" + StringToWideString(source) + L"@");
    WriteLineUnicode("@" + WidestringToString(wsource) + "@");
    return EXIT_SUCCESS;
}

5. Наконец, вам нужна мощная и полная поддержка символов Юникода в консоли. Я рекомендую ConEmu и установить в качестве терминала по умолчанию в Windows . Вам нужно подключить Visual Studio к ConEmu. Помните, что исполняемый файл Visual Studio - devenv.exe

Протестировано на Visual Studio 2017 с VC ++; станд = C ++ 17.

результат

Result1

Joma
источник
6

Вы могли бы также просто использовать узкий метод фасета ctype напрямую:

#include <clocale>
#include <locale>
#include <string>
#include <vector>

встроенный std :: string узкий (std :: wstring const & text)
{
    std :: locale const loc ("");
    wchar_t const * from = text.c_str ();
    std :: size_t const len ​​= text.size ();
    буфер std :: vector <char> (len + 1);
    std :: use_facet <std :: ctype <wchar_t>> (loc) .narrow (from, from + len, '_', & buffer [0]);
    return std :: string (& buffer [0], & buffer [len]);
}
Лигалайз
источник
6

На момент написания этого ответа поисковая система Google номер один "преобразовать строку wstring" попадет на эту страницу. Мой ответ показывает, как преобразовать строку в wstring, хотя это не фактический вопрос, и я, вероятно, должен удалить этот ответ, но это считается плохой формой. Вы можете перейти к этому ответу StackOverflow , который теперь имеет более высокий рейтинг, чем эта страница.


Вот способ объединения строковых, wstring и смешанных строковых констант в wstring. Используйте класс wstringstream.

#include <sstream>

std::string narrow = "narrow";
std::wstring wide = "wide";

std::wstringstream cls;
cls << " abc " << narrow.c_str() << L" def " << wide.c_str();
std::wstring total= cls.str();
Марк Лаката
источник
13
Это не преобразование строк в строки
poitroae
1
@ Майкл Не могли бы вы объяснить? Что по этому поводу неверно? Ваш комментарий не поможет без более подробной информации.
Nate
1
это преобразование строки в строку. т.е. противоположность вопроса.
Джефф МакКлинток
4

Помимо простого преобразования типов, вы также должны помнить о фактическом формате строки.

При компиляции для многобайтового набора символов Visual Studio и Win API предполагают UTF8 (собственно Windows-кодировка Windows-28591 ).
При компиляции для набора символов Unicode Visual Studio и Win API предполагают UTF16.

Таким образом, вы должны также преобразовать строку из формата UTF16 в формат UTF8, а не просто преобразовать в std :: string.
Это станет необходимым при работе с многосимвольными форматами, такими как некоторые нелатинские языки.

Идея состоит в том, чтобы решить, что std::wstring всегда представляет UTF16 .
И std::string всегда представляет UTF8 .

Это не обеспечивается компилятором, это скорее хорошая политика. Обратите внимание на строковые префиксы, которые я использую для определения UTF16 ( L ) и UTF8 ( u8 ).

Для преобразования между двумя типами вы должны использовать: std :: codecvt_utf8_utf16 <wchar_t>

#include <string>

#include <codecvt>

int main()
{

    std::string original8 = u8"הלו";

    std::wstring original16 = L"הלו";

    //C++11 format converter
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    //convert to UTF8 and std::string
    std::string utf8NativeString = convert.to_bytes(original16);

    std::wstring utf16NativeString = convert.from_bytes(original8);

    assert(utf8NativeString == original8);
    assert(utf16NativeString == original16);

    return 0;
}
Йохай Тиммер
источник
3

В моем случае я должен использовать многобайтовые символы (MBCS), и я хочу использовать std :: string и std :: wstring. И не могу использовать с ++ 11. Поэтому я использую mbstowcs и wcstombs.

Я делаю ту же функцию с использованием new, delete [], но это медленнее, чем это.

Это может помочь Как: конвертировать между различными типами строк

РЕДАКТИРОВАТЬ

Однако, в случае преобразования в строку wstring и исходную строку нет алфавита и многобайтовой строки, это не работает. Поэтому я меняю wcstombs на WideCharToMultiByte.

#include <string>

std::wstring get_wstr_from_sz(const char* psz)
{
    //I think it's enough to my case
    wchar_t buf[0x400];
    wchar_t *pbuf = buf;
    size_t len = strlen(psz) + 1;

    if (len >= sizeof(buf) / sizeof(wchar_t))
    {
        pbuf = L"error";
    }
    else
    {
        size_t converted;
        mbstowcs_s(&converted, buf, psz, _TRUNCATE);
    }

    return std::wstring(pbuf);
}

std::string get_string_from_wsz(const wchar_t* pwsz)
{
    char buf[0x400];
    char *pbuf = buf;
    size_t len = wcslen(pwsz)*2 + 1;

    if (len >= sizeof(buf))
    {
        pbuf = "error";
    }
    else
    {
        size_t converted;
        wcstombs_s(&converted, buf, pwsz, _TRUNCATE);
    }

    return std::string(pbuf);
}

РЕДАКТИРОВАТЬ, чтобы использовать «MultiByteToWideChar» вместо «wcstombs»

#include <Windows.h>
#include <boost/shared_ptr.hpp>
#include "string_util.h"

std::wstring get_wstring_from_sz(const char* psz)
{
    int res;
    wchar_t buf[0x400];
    wchar_t *pbuf = buf;
    boost::shared_ptr<wchar_t[]> shared_pbuf;

    res = MultiByteToWideChar(CP_ACP, 0, psz, -1, buf, sizeof(buf)/sizeof(wchar_t));

    if (0 == res && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        res = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);

        shared_pbuf = boost::shared_ptr<wchar_t[]>(new wchar_t[res]);

        pbuf = shared_pbuf.get();

        res = MultiByteToWideChar(CP_ACP, 0, psz, -1, pbuf, res);
    }
    else if (0 == res)
    {
        pbuf = L"error";
    }

    return std::wstring(pbuf);
}

std::string get_string_from_wcs(const wchar_t* pcs)
{
    int res;
    char buf[0x400];
    char* pbuf = buf;
    boost::shared_ptr<char[]> shared_pbuf;

    res = WideCharToMultiByte(CP_ACP, 0, pcs, -1, buf, sizeof(buf), NULL, NULL);

    if (0 == res && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        res = WideCharToMultiByte(CP_ACP, 0, pcs, -1, NULL, 0, NULL, NULL);

        shared_pbuf = boost::shared_ptr<char[]>(new char[res]);

        pbuf = shared_pbuf.get();

        res = WideCharToMultiByte(CP_ACP, 0, pcs, -1, pbuf, res, NULL, NULL);
    }
    else if (0 == res)
    {
        pbuf = "error";
    }

    return std::string(pbuf);
}
Хон
источник
Как я могу использовать "wcstombs_s" с gcc 4.8? Потому что я вижу, что это особенность C ++ 11.
Кристиан
@cristian Вы можете использовать «небезопасную» версию этой функции wcstombs().
Визор
3

Это решение вдохновлено решением dk123 , но использует зависящий от локали аспект codecvt. Результат находится в кодированной строке локали вместо UTF-8 (если она не установлена ​​как локаль):

std::string w2s(const std::wstring &var)
{
   static std::locale loc("");
   auto &facet = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(loc);
   return std::wstring_convert<std::remove_reference<decltype(facet)>::type, wchar_t>(&facet).to_bytes(var);
}

std::wstring s2w(const std::string &var)
{
   static std::locale loc("");
   auto &facet = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(loc);
   return std::wstring_convert<std::remove_reference<decltype(facet)>::type, wchar_t>(&facet).from_bytes(var);
}

Я искал это, но я не могу найти это. Наконец, я обнаружил, что могу получить правильный аспект, std::localeиспользуя std::use_facet()функцию с правильным именем типа. Надеюсь это поможет.

личина
источник
Визор, каковы преимущества (если таковые имеются) преобразования с зависимым от локали аспектом?
23
Если вы работаете со строками из системы, например из консоли ввода.
Визор
1

В случае , если кто - то заинтересован: мне нужен класс , который можно было бы использовать как взаимозаменяемые , где либо stringили wstringожидался. Следующий класс convertible_string, основанный на решении dk123 игровых , может быть инициализирован либо string, char const*, wstringили wchar_t const*и может быть назначен на или неявно преобразовать либо в stringили wstring(так можно передать в функцию , которые принимают либо).

class convertible_string
{
public:
    // default ctor
    convertible_string()
    {}

    /* conversion ctors */
    convertible_string(std::string const& value) : value_(value)
    {}
    convertible_string(char const* val_array) : value_(val_array)
    {}
    convertible_string(std::wstring const& wvalue) : value_(ws2s(wvalue))
    {}
    convertible_string(wchar_t const* wval_array) : value_(ws2s(std::wstring(wval_array)))
    {}

    /* assignment operators */
    convertible_string& operator=(std::string const& value)
    {
        value_ = value;
        return *this;
    }
    convertible_string& operator=(std::wstring const& wvalue)
    {
        value_ = ws2s(wvalue);
        return *this;
    }

    /* implicit conversion operators */
    operator std::string() const { return value_; }
    operator std::wstring() const { return s2ws(value_); }
private:
    std::string value_;
};
Джеймс Хиршорн
источник
1
Я предпочел бы хранить std::wstringв классе, чем хранить std::stringи делать преобразование, std::wstringкогда это необходимо, чтобы получить std::wstring. Потому что std::wstringэто несколько быстрее std::stringи лучше совместимо. Даже он потребляет больше памяти, чем std::string.
0xAA55
0
#include <boost/locale.hpp>
namespace lcv = boost::locale::conv;

inline std::wstring fromUTF8(const std::string& s)
{ return lcv::utf_to_utf<wchar_t>(s); }

inline std::string toUTF8(const std::wstring& ws)
{ return lcv::utf_to_utf<char>(ws); }
deep125
источник
-1

Я использую ниже, чтобы преобразовать wstring в строку.

std::string strTo;
char *szTo = new char[someParam.length() + 1];
szTo[someParam.size()] = '\0';
WideCharToMultiByte(CP_ACP, 0, someParam.c_str(), -1, szTo, (int)someParam.length(), NULL, NULL);
strTo = szTo;
delete szTo;
Arun
источник
Кажется, вам не хватает стандартного header ( <string>) и определения для WideCharToMultiByte()- это какая-то обертка std::wctomb()?
Тоби Спейт
-3
// Embarcadero C++ Builder 

// convertion string to wstring
string str1 = "hello";
String str2 = str1;         // typedef UnicodeString String;   -> str2 contains now u"hello";

// convertion wstring to string
String str2 = u"hello";
string str1 = UTF8string(str2).c_str();   // -> str1 contains now "hello"
necips
источник
3
пожалуйста, объясните, что вы там делаете в своем ответе, иначе это может привести к удалению
CodeFanatic
1
Откуда берется функция UTF8string?
Жан-Кристоф Бланшар