Come convertire wstring in stringa?


204

La domanda è: come convertire wstring in stringa?

Ho il prossimo esempio:

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

l'output con la riga commentata è:

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

ma senza è solo:

std::wstring =    Hello

C'è qualcosa di sbagliato nell'esempio? Posso fare la conversione come sopra?

MODIFICARE

Nuovo esempio (tenendo conto di alcune risposte) è

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

L'output è:

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

pertanto lo stringstream non può essere utilizzato per convertire wstring in stringa.


4
Come puoi fare questa domanda senza specificare anche le codifiche?
David Heffernan,

5
@tenfour: perché usarlo std::wstring? stackoverflow.com/questions/1049947/…
dalle

11
@dalle Se disponi di dati già codificati con UTF-16, se UTF-16 è considerato dannoso è piuttosto discutibile. E per quello che vale, non credo che nessuna forma di trasformazione sia dannosa; ciò che è dannoso è che le persone pensano di capire Unicode quando in realtà non lo fanno.
David Heffernan,

2
Deve essere una soluzione multipiattaforma?
ali_bahoo,

2
Lo standard @dalle c ++ non menziona utf in alcun modo (utf-8 o utf-16). Hai un link dove dice perché utf-16 non può essere codificato con wstring?
BЈовић,

Risposte:


31

Ecco una soluzione elaborata basata sugli altri suggerimenti:

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

Questo di solito funzionerà per Linux, ma creerà problemi su Windows.


@Phillip: quale parte del codice dipende dalla c-locale? è std::setlocale(LC_ALL, "");davvero necessario?
smerlin,

2
l'utilizzo std::wcout.imbue(locale)dovrebbe fare anche il lavoro e ha il vantaggio di non cambiare alcuno stato globale.
smerlin,

32
Il std::wstring_convertda C ++ 11 avvolge molto di questo rumore.
Cubbi,

7
@Philipp, cosa vuoi dire con "creerà problemi su Windows"? Che tipo di problemi?
Gili,

1
Il codice sopra riportato (come copiato) mi dà un *** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***su Linux 64-bit (gcc 4.7.3). Qualcun altro sta vivendo questo?
hogliux,

312

Come ha sottolineato Cubbi in uno dei commenti, std::wstring_convert(C ++ 11) fornisce una soluzione semplice e ordinata (è necessario #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 );

Stavo usando una combinazione di wcstombsnoiosa allocazione / deallocazione della memoria prima di imbattermi in questo.

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

Aggiornamento (2013/11/28)

È possibile dichiarare una sola riga (Grazie Guss per il tuo commento):

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

Le funzioni wrapper possono essere dichiarate come segue: (Grazie ArmanSchwarz per il tuo commento)

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: c'è qualche controversia sul fatto che string/ wstringdebba essere passato a funzioni come riferimenti o letterali (a causa di C ++ 11 e aggiornamenti del compilatore). Lascio la decisione alla persona che esegue, ma vale la pena saperlo.

Nota: sto usando std::codecvt_utf8il codice sopra, ma se non stai usando UTF-8 dovrai cambiarlo con la codifica appropriata che stai usando:

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


25
Per favore +1 : questo è il modo standard C ++ ufficiale per eseguire la conversione di stringhe. Puoi anche usare from_bytes per convertire in altro modo. Perché personalmente mi piacciono i one-liner, ecco la mia versione:std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
Guss,

7
Sembra che en.cppreference.com/w/cpp/header/codecvt non sia disponibile da g ++ 4.8.2. I due metodi s2ws e ws2s attualmente non funzionano con Linux
Begui,

5
Sembra che questo sia obsoleto ( stackoverflow.com/a/42946556/211176 ). Il mio compilatore genera errori quando provo a eseguire questo codice
adam_0


5
Per chiunque si preoccupi di C ++ 17 e ulteriore compatibilità (a causa della deprecazione), consultare: stackoverflow.com/a/18597384/6205379
Timo

128

Soluzione da: 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;

Attenzione che non esiste alcuna conversione del set di caratteri. Ciò che fa è semplicemente assegnare ogni ripetizione wchar_ta una char- una conversione troncata. Usa lo std :: string c'tor :

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

Come indicato nei commenti:

i valori 0-127 sono identici praticamente in ogni codifica, quindi troncando i valori che sono tutti inferiori a 127 si ottiene lo stesso testo. Inserisci un carattere cinese e vedrai il fallimento.

-

i valori 128-255 della codepage di Windows 1252 (impostazione predefinita di Windows in inglese) e i valori 128-255 dell'unicode sono per lo più gli stessi, quindi se questa è la codepage che stai usando la maggior parte di quei caratteri dovrebbe essere troncata ai valori corretti. (Mi aspettavo che á e õ funzionassero, so che il nostro codice al lavoro si basa su questo per é, che riparerò presto)

E nota che i punti di codice nella gamma 0x80 - 0x9Fin win1252 saranno non funzionerà. Questo include , œ, ž, Ÿ, ...


2
Stranamente, questo funziona su Visual Studio 10. Cosa sta succedendo? Ciò dovrebbe causare un'assegnazione troncante da wchar_t a char per tutti gli elementi della stringa originale.
Pedro Lamarão,

6
... quando si tratta di caratteri non latini.
JavaRunner,

8
@ PedroLamarão: i valori 0-127 sono identici praticamente in ogni codifica, quindi troncando i valori che sono tutti inferiori a 127 si ottiene lo stesso testo. Inserisci un carattere cinese e vedrai il fallimento.
Mooing Duck

3
@ PedroLamarão: i valori 128-255 della codepage di Windows 1252 (impostazione predefinita di Windows in inglese) e i valori 128-255 dell'unicode sono per lo più gli stessi, quindi se questa è la tabella codici che stai utilizzando la maggior parte di questi caratteri dovrebbe essere troncata per la corretta valori. (Mi aspettavo che á e õ funzionassero, so che il nostro codice di lavoro si basa su questo per é, che
riparerò

2
Funziona benissimo. MSVS 2015 e MSVS 2017 e MINGW / g ++ e clang ++. Legit ++ 1.
Nikos,

11

Invece di includere le impostazioni internazionali e tutte quelle cose fantasiose, se conosci FACT la tua stringa è convertibile, fai questo:

#include <iostream>
#include <string>

using namespace std;

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

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

Esempio live qui


2
+1 perché è una soluzione semplice che funziona per alcuni scenari (per una definizione libera di "lavori", potrei aggiungere).
corvo

2
Quasi la stessa cosa della soluzione di namar0x0309, che è molto più elegante di IMHO. Ma sono solo io.
Onitake,

Ho modificato il tuo codice affinché funzioni effettivamente con una modifica minima ;-)
rubenvb,

9
-1 Se hai una stringa, è probabile che tu abbia a che fare con personaggi multibyte. Se potessi sapere che la stringa è banalmente convertibile, in primo luogo non gestiresti una stringa. Più probabilmente, hai a che fare con un'altra libreria che si aspetta che tu gestisca correttamente il wstring. Troncare il wchars è solo chiedere un bug difficile da rintracciare in seguito. Inoltre, dovresti usare "string result (w.begin (), w.end ());" se lo avessi fatto, per evitare un ciclo che potrebbe innescare molte riallocazioni.
Kian,

7

Credo che il modo ufficiale debba ancora passare attraverso codecvtsfaccettature (è necessaria una sorta di traduzione attenta alle impostazioni locali), come in

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

o qualcosa del genere, non ho un codice funzionante in giro. Ma non sono sicuro di quante persone oggigiorno utilizzino quel macchinario e quante semplicemente chiedano puntatori alla memoria e lasciano che ICU o qualche altra libreria gestisca i dettagli cruenti.


7

Esistono due problemi con il codice:

  1. La conversione in const std::string s( ws.begin(), ws.end() );non è necessaria per mappare correttamente i caratteri ampi alla loro controparte stretta. Molto probabilmente, ogni personaggio largo sarà semplicemente convertito in char.
    La soluzione a questo problema è già stata data nella risposta di kem e coinvolge la narrowfunzione della ctypesfaccettatura del locale .

  2. Stai scrivendo l'output su entrambi std::coute std::wcoutnello stesso programma. Entrambi coute wcoutsono associati allo stesso flusso ( stdout) e i risultati dell'utilizzo dello stesso flusso sia come flusso orientato al byte (come coutfa) che come flusso orientato al largo (come wcoutfa) non sono definiti.
    L'opzione migliore è evitare di mescolare output stretto e largo allo stesso flusso (sottostante). Per stdout/ cout/ wcout, puoi provare a cambiare l'orientamento di stdoutquando si passa da un'uscita ampia a stretta (o viceversa):

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

Sì, questo risolve il problema con l'utilizzo di cout e wcout.
BЈовић,

7

Codifica predefinita attivata:

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

Questo codice ha due forme per convertire std :: string in std :: wstring e std :: wstring in std :: string. Se si annulla # se definito WIN32, si ottiene lo stesso risultato.

1. std :: stringa in 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 in 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. Su Windows devi stampare Unicode, usando 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. Sul programma principale.

#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. Infine, è necessario un supporto completo e potente per i caratteri Unicode nella console. Raccomando ConEmu e impostarlo come terminale predefinito su Windows . È necessario collegare Visual Studio a ConEmu. Ricorda che il file exe di Visual Studio è devenv.exe

Testato su Visual Studio 2017 con VC ++; std = c ++ 17.

Risultato

result1


6

Potresti anche usare direttamente il metodo stretto della sfaccettatura del ctype direttamente:

#include <clocale>
#include <locale>
#include <stringa>
#include <vector>

inline std :: string narrow (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> buffer (len + 1);
    std :: use_facet <std :: ctype <wchar_t>> (loc) .narrow (da, da + len, '_', & buffer [0]);
    return std :: string (& buffer [0], & buffer [len]);
}

6

Al momento della stesura di questa risposta, la ricerca google numero uno per "convertire stringa wstring" ti atterrerebbe su questa pagina. La mia risposta mostra come convertire la stringa in wstring, sebbene questa NON sia la vera domanda, e probabilmente dovrei cancellare questa risposta ma è considerata una forma errata. Puoi passare a questa risposta StackOverflow , che ora è classificata più in alto rispetto a questa pagina.


Ecco un modo per combinare stringa, wstring e costanti di stringa mista a wstring. Usa la 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();

13
Questa non è una conversione da stringa a stringa
poitroae,

1
@Michael Puoi spiegarmi per favore? Che dire di questo non è corretto? Il tuo commento non è utile senza ulteriori dettagli.
Nate,

1
questa è una stringa per la conversione di wstring. cioè l'opposto della domanda.
Jeff McClintock,

4

Oltre a convertire i tipi, dovresti anche essere consapevole del formato effettivo della stringa.

Durante la compilazione per il set di caratteri multi-byte, Visual Studio e l'API Win assumono UTF8 (in realtà la codifica di Windows che è Windows-28591 ).
Durante la compilazione per il set di caratteri Unicode Visual Studio e l'API Win assume UTF16.

Quindi, è necessario convertire anche la stringa dal formato UTF16 al formato UTF8 e non solo convertire in std :: string.
Ciò sarà necessario quando si lavora con formati multi-carattere come alcune lingue non latine.

L'idea è quella di decidere che rappresenta std::wstring sempre UTF16 .
E rappresenta std::string sempre UTF8 .

Questo non è applicato dal compilatore, è più una buona politica da avere. Nota i prefissi di stringa che utilizzo per definire UTF16 ( L ) e UTF8 ( u8 ).

Per convertire tra i 2 tipi, dovresti usare: 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

Nel mio caso, devo usare il carattere multibyte (MBCS) e voglio usare std :: string e std :: wstring. E non posso usare c ++ 11. Quindi uso mbstowcs e wcstombs.

Faccio la stessa funzione con l'utilizzo di new, delete [], ma è più lento di così.

Questo può aiutare Procedura: convertire tra vari tipi di stringa

MODIFICARE

Tuttavia, in caso di conversione in wstring e stringa di origine non c'è alfabeto e stringa multibyte, non funziona. Quindi cambio wcstombs in 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);
}

MODIFICA per utilizzare "MultiByteToWideChar" anziché "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);
}

Come posso usare "wcstombs_s" con gcc 4.8? Perché vedo che è la funzionalità C ++ 11.
cristian,

@cristian È possibile utilizzare la versione "non sicura" di questa funzione wcstombs().
Vizor,

3

Questa soluzione è ispirata alla soluzione di dk123 , ma utilizza un aspetto codecvt dipendente dalla locale. Il risultato è una stringa codificata in locale anziché UTF-8 (se non è impostata come locale):

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

Lo stavo cercando, ma non riesco a trovarlo. Alla fine ho scoperto che posso ottenere la faccetta giusta std::localeusando la std::use_facet()funzione con il giusto nome. Spero che questo ti aiuti.


Vizor, quali sono i vantaggi (se presenti) della conversione con il facet dipendente dalla locale?
Marc.2377,

Se lavori con stringhe dal sistema, ad esempio dall'input della console.
Vizor,

1

Nel caso in cui chiunque altro sia interessato: avevo bisogno di una classe che potrebbe essere utilizzato in modo intercambiabile, ovunque sia una stringo wstringci si aspettava. La classe seguente convertible_string, sulla base di soluzione dk123 , può essere inizializzato con un string, char const*, wstringo wchar_t const*e può essere assegnato a da o convertito in modo implicito o un stringo wstring(quindi può essere passato in un funzioni che prendono o).

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
Preferirei archiviare un std::wstringnella classe, piuttosto che archiviare std::stringe fare una conversione std::wstringquando necessario per ottenere un std::wstring. Perché std::wstringè un po 'più veloce di std::stringed è meglio compatibile. Anche consuma più memoria di 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); }

-1

Sto usando di seguito per convertire wstring in stringa.

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;

Sembra che manchi un'intestazione standard ( <string>) e una definizione per WideCharToMultiByte()- c'è qualche wrapper in giro 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"

3
per favore spiega cosa stai facendo lì nella tua risposta, altrimenti potrebbe essere cancellato
CodeFanatic

1
Da dove viene la funzione UTF8string?
Jean-Christophe Blanchard,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.