Como converter wstring em string?

204

A questão é como converter wstring em string?

Eu tenho o próximo exemplo:

#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;
}

a saída com linha comentada é:

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

mas sem é apenas:

std::wstring =    Hello

Há algo errado no exemplo? Posso fazer a conversão como acima?

EDITAR

Um novo exemplo (levando em consideração algumas respostas) é

#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;
}

A saída é:

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

portanto, o stringstream não pode ser usado para converter wstring em string.

BЈовић
fonte
4
Como você pode fazer essa pergunta sem especificar também as codificações?
David Heffernan
5
@tenfour: Por que usar std::wstring? stackoverflow.com/questions/1049947/…
dalle
11
@dalle Se você possui dados que já estão codificados com o UTF-16, se o UTF-16 é considerado prejudicial ou não, é um pouco discutível. E pelo que vale a pena, não acho que nenhuma forma de transformação seja prejudicial; o que é prejudicial é que as pessoas acham que entendem o Unicode quando na verdade não o fazem.
David Heffernan
2
Tem que ser uma solução multiplataforma?
ali_bahoo
2
O padrão @dalle c ++ não menciona utf de forma alguma (utf-8 ou utf-16). Tem um link onde diz por que o utf-16 não pode ser codificado com o wstring?
BЈовић

Respostas:

31

Aqui está uma solução elaborada com base nas outras sugestões:

#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;
  }
}

Isso normalmente funciona para Linux, mas cria problemas no Windows.

Philipp
fonte
@Phillip: qual parte do código depende da localidade c? é std::setlocale(LC_ALL, "");realmente necessário?
smerlin
2
O uso também std::wcout.imbue(locale)deve fazer o trabalho e tem o benefício de não alterar nenhum estado global.
smerlin
32
O std::wstring_convertdo C ++ 11 envolve muito desse ruído.
Cubbi 27/09/11
7
@ Philipp, o que você quer dizer com "criará problemas no Windows"? Que tipo de problemas?
Gili
1
O código acima fornece (como copiado) fornece um *** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***no Linux de 64 bits (gcc 4.7.3). Mais alguém está passando por isso?
hogliux
312

Como Cubbi apontou em um dos comentários, std::wstring_convert(C ++ 11) fornece uma solução simples e elegante (você precisa #include <locale>e <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 );

Eu estava usando uma combinação de wcstombsalocação / desalocação tediosa de memória antes de me deparar com isso.

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

update (28.11.2013)

Um liners pode ser declarado assim (obrigado Guss pelo seu comentário):

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

As funções do wrapper podem ser definidas da seguinte forma: (Obrigado ArmanSchwarz pelo seu comentário)

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);
}

Nota: existe alguma controvérsia sobre se string/wstring deve ser transmitida para funções como referências ou como literais (devido ao C ++ 11 e atualizações do compilador). Vou deixar a decisão para a pessoa que está implementando, mas vale a pena saber.

Nota: Estou usando std::codecvt_utf8o código acima, mas se você não estiver usando UTF-8, precisará alterá-lo para a codificação apropriada que estiver usando:

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

dk123
fonte
25
Por favor, +1 : esta é a maneira oficial padrão do C ++ de fazer a conversão de strings. Você também pode usar from_bytes para converter para o outro lado. Porque eu pessoalmente gosto de one-liners, aqui está a minha versão:std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
Guss
7
Parece que en.cppreference.com/w/cpp/header/codecvt não está disponível no g ++ 4.8.2. Os dois s2ws e métodos ws2s atualmente não trabalhar em Linux
Begui
5
Parece que isso foi preterido ( stackoverflow.com/a/42946556/211176 ). Meu compilador gera erros quando tento executar esse código
adam_0
5
Para qualquer pessoa preocupada com C ++ 17 e compatibilidade adicional (devido a descontinuação), consulte: stackoverflow.com/a/18597384/6205379
Timo
128

Solução de: 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;

Cuidado que não há nenhuma conversão de conjunto de caracteres em andamento aqui. O que isso faz é simplesmente atribuir cada iterado wchar_ta uma char- uma conversão truncante. Ele usa o std :: string c'tor :

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

Conforme declarado nos comentários:

os valores 0-127 são idênticos em praticamente todas as codificações, portanto, truncar valores menores que 127 resulta no mesmo texto. Coloque um caractere chinês e você verá o fracasso.

-

os valores 128-255 da página de código do Windows 1252 (o padrão em inglês do Windows) e os valores 128-255 do unicode são os mesmos. Portanto, se essa é a página de código que você está usando, a maioria desses caracteres deve ser truncada para os valores corretos. (Eu totalmente esperava que á e õ funcionassem, eu sei que nosso código no trabalho depende disso para é, que em breve corrigirei)

E nota que os pontos de código na faixa 0x80 - 0x9Fem Win1252 vai não funcionam. Isto inclui , œ, ž, Ÿ, ...

namar0x0309
fonte
2
Estranhamente, isso funciona no Visual Studio 10. O que está acontecendo? Isso deve causar uma atribuição truncada de wchar_t para char para todos os elementos da string original.
Pedro Lamarão
6
... quando se trata de caracteres não latinos.
JavaRunner 31/05
8
@ PedroLamarão: os valores 0-127 são idênticos em praticamente todas as codificações, portanto, truncar valores inferiores a 127 resulta no mesmo texto. Coloque um caractere chinês e você verá o fracasso.
Mooing Duck
3
@ PedroLamarão: os valores 128-255 da página de código do Windows 1252 (o padrão em inglês do Windows) e os valores 128-255 do unicode são basicamente os mesmos, portanto, se essa é a página de código que você está usando, a maioria desses caracteres deve ser truncada para o correto valores. (Eu esperava totalmente A e O para o trabalho, eu sei que o nosso código no trabalho depende desse para E, que em breve vou correção)
Mooing Duck
2
Isso funciona muito bem. MSVS 2015 e MSVS 2017 e MINGW / g ++ e clang ++. Legit ++ 1.
Nikos
11

Em vez de incluir o código do idioma e todas essas coisas sofisticadas, se você conhece o FACT, sua string é conversível, faça o seguinte:

#include <iostream>
#include <string>

using namespace std;

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

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

Exemplo ao vivo aqui

rubenvb
fonte
2
+1 porque é uma solução simples que funciona para alguns cenários (para uma definição flexível de "funciona", devo acrescentar).
Raven #
2
Quase a mesma coisa que a solução namar0x0309, que é muito mais elegante no IMHO. Mas sou só eu.
Onitake
I spiffied o seu código para realmente trabalhar com modificações mínimas ;-)
rubenvb
9
-1 Se você tem um wstring, é provável que esteja lidando com caracteres multibyte. Se você soubesse que a string é trivialmente conversível, não estaria lidando com uma string em primeiro lugar. Provavelmente, você está lidando com outra biblioteca que espera que você lide com o wstring corretamente. Truncar os wchars está apenas implorando por um erro difícil de rastrear mais tarde. Além disso, você deve usar "string result (w.begin (), w.end ());" se você fosse fazer isso, para evitar um loop que poderia desencadear muitas realocações.
Kian
7

Eu acredito que a maneira oficial ainda é seguir todas as codecvtfacetas (você precisa de algum tipo de tradução com reconhecimento de local), como em

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

ou algo assim, não tenho código de trabalho por aí. Mas não sei ao certo quantas pessoas hoje em dia usam esse mecanismo e quantas simplesmente pedem ponteiros para a memória e permitem que a UTI ou alguma outra biblioteca lide com os detalhes sangrentos.

Christopher Creutzig
fonte
7

Há dois problemas com o código:

  1. A conversão em const std::string s( ws.begin(), ws.end() );não é necessária para mapear corretamente os caracteres largos para sua contraparte estreita. Provavelmente, cada caractere amplo será tipificado apenas para char.
    A resolução para esse problema já é dada na resposta pelo kem e envolve a narrowfunção da ctypefaceta da localidade .

  2. Você está gravando saída para ambos std::coute std::wcoutno mesmo programa. Ambos coute wcoutestão associados ao mesmo fluxo ( stdout) e os resultados do uso do mesmo fluxo como um fluxo orientado a bytes (como coutfaz) e um fluxo orientado a largura (como wcout) não são definidos.
    A melhor opção é evitar misturar saída estreita e ampla no mesmo fluxo (subjacente). Para stdout/ cout/ wcout, você pode tentar alternar a orientação stdoutao alternar entre saída ampla e estreita (ou vice-versa):

    #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;
    }
Bart van Ingen Schenau
fonte
Sim, isso resolve o problema do uso de cout e wcout.
BЈовић
7

Codificação padrão ativada em:

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

Esse código possui dois formulários para converter std :: string em std :: wstring e std :: wstring em std :: string. Se você negar #if definido WIN32, você obtém o mesmo resultado.

1. std :: string para std :: wstring

• WinAPI MultiByteToWideChar

_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 para 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. No Windows, você precisa imprimir unicode, usando o 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. No programa principal.

#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. Finalmente, você precisa de um suporte completo e poderoso para caracteres unicode no console. Eu recomendo o ConEmu e defina como terminal padrão no Windows . Você precisa conectar o Visual Studio ao ConEmu. Lembre-se que o arquivo exe do Visual Studio é devenv.exe

Testado no Visual Studio 2017 com VC ++; std = c ++ 17.

Resultado

Resultado1

Joma
fonte
6

Você também pode usar o método estreito da faceta ctype diretamente:

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

std inline :: string estreito (std :: wstring const & text)
{
    std :: locale const loc ("");
    wchar_t const * de = texto.c_str ();
    std :: size_t const len ​​= text.size ();
    buffer std :: vector <char> (len + 1);
    std :: use_facet <std :: ctype <wchar_t>> (loc) .narrow (de, de + len, '_', & buffer [0]);
    retornar std :: string (& buffer [0], & buffer [len]);
}
legalizar
fonte
6

No momento em que escrevemos essa resposta, a pesquisa número um no Google por "converter string wstring" o colocaria nessa página. Minha resposta mostra como converter string em wstring, embora essa NÃO seja a pergunta real, e eu provavelmente deva excluir essa resposta, mas isso é considerado uma forma incorreta. Você pode pular para esta resposta do StackOverflow , que agora é mais alta do que esta página.


Aqui está uma maneira de combinar string, wstring e constantes de string mistas com o wstring. Use a classe 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();
Mark Lakata
fonte
13
Este não é um wstring para conversão de cadeia
poitroae
1
@ Michael Você pode me explicar? Que tal isso está incorreto? Seu comentário não é útil sem mais detalhes.
Nate
1
esta é uma string para conversão de string. ou seja, o oposto da pergunta.
Jeff McClintock
4

Além de apenas converter os tipos, você também deve estar ciente do formato real da string.

Ao compilar para o conjunto de caracteres de vários bytes, o Visual Studio e a API do Win assumem UTF8 (na verdade, a codificação de janelas é Windows-28591 ).
Ao compilar para o conjunto de caracteres Unicode, o Visual studio e a API Win assumem UTF16.

Portanto, você deve converter a sequência do formato UTF16 para UTF8 também, e não apenas converter para std :: string.
Isso será necessário ao trabalhar com formatos com vários caracteres, como alguns idiomas não latinos.

A idéia é decidir que std::wstring sempre representa UTF16 .
E std::string sempre representa UTF8 .

Isso não é imposto pelo compilador, é mais uma boa política. Observe os prefixos de string que eu uso para definir UTF16 ( L ) e UTF8 ( u8 ).

Para converter entre os dois tipos, você deve usar: 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;
}
Yochai Timmer
fonte
3

No meu caso, eu tenho que usar o caractere multibyte (MBCS) e quero usar std :: string e std :: wstring. E não pode usar c ++ 11. Então eu uso mbstowcs e wcstombs.

Faço a mesma função com o uso de new, delete [], mas é mais lento que isso.

Isso pode ajudar Como converter entre vários tipos de seqüência de caracteres

EDITAR

No entanto, no caso de converter para wstring e string de origem, não há alfabeto nem string de vários bytes, não está funcionando. Então eu mudo wcstombs para 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);
}

EDIT para usar 'MultiByteToWideChar' em vez de '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);
}
ele no
fonte
Como posso usar "wcstombs_s" com o gcc 4.8? Porque eu vejo que é o recurso C ++ 11.
cristian
@cristian Você pode usar a versão "não segura" desta função wcstombs().
Vizor
3

Esta solução é inspirada na solução do dk123 , mas usa uma faceta codecvt dependente da localidade. O resultado está na cadeia codificada por código de idioma em vez de UTF-8 (se não estiver definido como código de idioma):

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);
}

Eu estava procurando, mas não consigo encontrá-lo. Finalmente, descobri que posso obter a faceta certa ao std::localeusar a std::use_facet()função com o nome correto. Espero que isto ajude.

Viseira
fonte
Vizor, quais são as vantagens (se houver) de converter com a faceta dependente da localidade?
Marc.2377 12/09/19
Se você trabalha com seqüências de caracteres do sistema, da entrada do console, por exemplo.
Vizor
1

Caso alguém mais esteja interessado: eu precisava de uma classe que pudesse ser usada de forma intercambiável, onde quer que fosse stringou wstringfosse esperado. A classe a seguir convertible_string, com base na solução de dk123 , pode ser inicializado com qualquer um string, char const*, wstringou wchar_t const*e pode ser atribuído a pelo ou implicitamente convertidos em qualquer um stringou wstring(assim pode ser passado para uma série de funções que tomam qualquer um).

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_;
};
James Hirschorn
fonte
1
Prefiro armazenar um std::wstringna classe, do que armazenar std::stringe fazer uma conversão para std::wstringquando necessário std::wstring. Porque std::wstringé um pouco mais rápido std::stringe é melhor compatível. Mesmo ele consome mais memória do que 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
fonte
-1

Estou usando abaixo para converter wstring em string.

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;
Uma corrida
fonte
Parece que está faltando um cabeçalho padrão ( <string>) e uma definição para WideCharToMultiByte()- isso é algum invólucro std::wctomb()?
Toby Speight
-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
fonte
3
por favor explicar o que ure fazendo lá em sua resposta, então ele pode obter deletet
CodeFanatic
1
De onde vem a função UTF8string?
Jean-Christophe Blanchard