C++ Convert string (ou char*) en wstring (ou wchart*)

string s = "おはよう";
wstring ws = FUNCTION(s, ws);

comment attribuer le contenu de s à ws?

a cherché google et utilisé certaines techniques, mais ils ne peuvent pas attribuer le contenu exact. Le contenu est déformé.

131
demandé sur kennytm 2010-04-04 11:35:00

13 réponses

en supposant que la chaîne de saisie dans votre exemple (փ) est une chaîne UTF-8 encodée (ce qui n'est pas le cas, à première vue, mais supposons que ce soit pour cette explication :-)) représentation d'une chaîne Unicode de votre intérêt, alors votre problème peut être entièrement résolu avec la bibliothèque standard (C++11 et plus récente) seule.

the TL;DR version:

#include <locale>
#include <codecvt>
#include <string>

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string narrow = converter.to_bytes(wide_utf16_source_string);
std::wstring wide = converter.from_bytes(narrow_utf8_source_string);

plus longue en ligne compilable et runnable exemple:

(ils montrent tous le même exemple. Il y a juste beaucoup de redondance...)

Note (ancienne) :

comme indiqué dans les commentaires et expliqué dans https://stackoverflow.com/a/17106065/6345 il y a des cas où l'utilisation de la bibliothèque standard pour convertir entre UTF-8 et UTF-16 pourrait donner des différences inattendues dans les résultats sur différentes plateformes. Pour une meilleure conversion, considérer std::codecvt_utf8 comme décrit sur http://en.cppreference.com/w/cpp/locale/codecvt_utf8

Note (nouvelle) :

étant donné que l'en-tête codecvt est déprécié en C++17, certains se sont inquiétés de la solution présentée dans cette réponse. Cependant, le Comité des normes c++ a ajouté une déclaration importante dans http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html dire

cette composante de bibliothèque doit être retirée à L'Annexe D, le long du côté , jusqu'à ce qu'un remplacement convenable soit normalisé.

donc dans un avenir prévisible, la solution codecvt dans cette réponse est sûre et portable.

185
répondu Johann Gerell 2017-07-28 07:31:08
int StringToWString(std::wstring &ws, const std::string &s)
{
    std::wstring wsTmp(s.begin(), s.end());

    ws = wsTmp;

    return 0;
}
38
répondu Pietro M 2012-01-23 09:54:13

votre question n'est pas précisée. Strictement, cet exemple est une erreur de syntaxe. Cependant, std::mbstowcs c'est probablement ce que vous cherchez.

il s'agit d'une fonction de bibliothèque C et fonctionne sur des tampons, mais voici un idiome facile à utiliser, gracieuseté de TBohne (anciennement Mooing Duck):

std::wstring ws(s.size(), L' '); // Overestimate number of code points.
ws.resize(std::mbstowcs(&ws[0], s.c_str(), s.size())); // Shrink to fit.
26
répondu Potatoswatter 2015-07-19 02:28:04

API Windows seulement, pré C++11 implémentation, dans le cas où quelqu'un en a besoin:

#include <stdexcept>
#include <vector>
#include <windows.h>

using std::runtime_error;
using std::string;
using std::vector;
using std::wstring;

wstring utf8toUtf16(const string & str)
{
   if (str.empty())
      return wstring();

   size_t charsNeeded = ::MultiByteToWideChar(CP_UTF8, 0, 
      str.data(), (int)str.size(), NULL, 0);
   if (charsNeeded == 0)
      throw runtime_error("Failed converting UTF-8 string to UTF-16");

   vector<wchar_t> buffer(charsNeeded);
   int charsConverted = ::MultiByteToWideChar(CP_UTF8, 0, 
      str.data(), (int)str.size(), &buffer[0], buffer.size());
   if (charsConverted == 0)
      throw runtime_error("Failed converting UTF-8 string to UTF-16");

   return wstring(&buffer[0], charsConverted);
}
16
répondu Alex Che 2014-11-13 17:14:27

si vous utilisez Windows / Visual Studio et que vous devez convertir une chaîne de caractères en wstring, vous pouvez utiliser:

#include <AtlBase.h>
#include <atlconv.h>
...
string s = "some string";
CA2W ca2w(s.c_str());
wstring w = ca2w;
printf("%s = %ls", s.c_str(), w.c_str());

même procédure pour convertir un wstring en chaîne (parfois vous devrez spécifier un codepage ):

#include <AtlBase.h>
#include <atlconv.h>
...
wstring w = L"some wstring";
CW2A cw2a(w.c_str());
string s = cw2a;
printf("%s = %ls", s.c_str(), w.c_str());

vous pouvez spécifier un codepage et même UTF8 (c'est assez agréable en travaillant avec JNI / Java ).

CA2W ca2w(str, CP_UTF8);

si vous voulez en savoir plus sur codepages il y a un article intéressant sur Joel sur le logiciel: le Minimum absolu tout développeur de logiciel absolument, positivement doit savoir sur Unicode et jeux de caractères .

ces Macro CA2W (Convertissez Ansi en wide = unicode) font partie des Macros de Conversion ATL et MFC String. , échantillons inclus.

parfois, vous devrez désactiver l'avertissement de sécurité #4995', Je ne connais pas d'autre solution (pour moi, cela arrive quand j'ai compilé pour WindowsXp en VS2012).

#pragma warning(push)
#pragma warning(disable: 4995)
#include <AtlBase.h>
#include <atlconv.h>
#pragma warning(pop)

Edit: Eh bien, selon cet article L'article de Joel semble être: "tout en divertissant, il est assez léger sur les détails techniques réels". Article: Ce Que Chaque Programmeur Absolument, Positivement Doit Savoir Sur L'Encodage Et Les Jeux De Caractères Pour Travailler Avec Le Texte .

11
répondu lmiguelmh 2014-11-10 15:26:18

de char* à wstring :

char* str = "hello worlddd";
wstring wstr (str, str+strlen(str));

de string à wstring :

string str = "hello worlddd";
wstring wstr (str.begin(), str.end());

notez que cela ne fonctionne bien que si la chaîne convertie ne contient que des caractères ASCII.

10
répondu Ghominejad 2013-07-14 13:16:18

Voici une façon de combiner string , wstring et des constantes de chaîne mélangées à wstring . Utilisez 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();
10
répondu Mark Lakata 2015-06-01 18:34:37

utilisant Boost.Paramètres régionaux:

ws = boost::locale::conv::utf_to_utf<wchar_t>(s);
6
répondu vladon 2015-09-21 09:42:31

cette variante est ma préférée dans la vie réelle. Il convertit L'entrée si elle est valide UTF-8, en wstring . Si l'entrée est corrompue, le wstring est construit à partir des octets simples. C'est extrêmement utile si vous ne pouvez pas vraiment être sûr de la qualité de vos données d'entrée.

std::wstring convert(const std::string& input)
{
    try
    {
        std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
        return converter.from_bytes(input);
    }
    catch(std::range_error& e)
    {
        size_t length = input.length();
        std::wstring result;
        result.reserve(length);
        for(size_t i = 0; i < length; i++)
        {
            result.push_back(input[i] & 0xFF);
        }
        return result;
    }
}
3
répondu Paramaeleon 2016-08-18 12:33:38

méthode s2ws fonctionne bien. Espoir aide.

std::wstring s2ws(const std::string& s) {
    std::string curLocale = setlocale(LC_ALL, ""); 
    const char* _Source = s.c_str();
    size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1;
    wchar_t *_Dest = new wchar_t[_Dsize];
    wmemset(_Dest, 0, _Dsize);
    mbstowcs(_Dest,_Source,_Dsize);
    std::wstring result = _Dest;
    delete []_Dest;
    setlocale(LC_ALL, curLocale.c_str());
    return result;
}
1
répondu hahakubile 2013-09-03 15:57:04

basé sur mes propres tests (sur windows 8, vs2010) mbstowcs peut endommager la chaîne originale, il ne fonctionne qu'avec la page de code ANSI. Si MultiByteToWideChar/WideCharToMultiByte peut aussi causer la corruption de chaîne - mais ils ont tendance à remplacer les caractères qu'ils ne savent pas avec"?"points d'interrogation, mais mbstowcs a tendance à s'arrêter quand il rencontre caractère inconnu et couper chaîne à ce point précis. (J'ai testé des caractères vietnamiens sur des fenêtres finlandaises).

So préférez la fonction api Multi*-windows aux fonctions analogiques ANSI C.

aussi ce que j'ai remarqué le plus court moyen d'encoder la chaîne d'un codepage à un autre n'est pas D'utiliser les appels de fonction api MultiByteToWideChar/WideCharToMultiByte mais leurs macros ATL analogiques: W2A / A2W.

ainsi la fonction analogique mentionnée ci-dessus ressemblerait à:

wstring utf8toUtf16(const string & str)
{
   USES_CONVERSION;
   _acp = CP_UTF8;
   return A2W( str.c_str() );
}

_acp est déclaré dans la macro USES_CONVERSION.

ou aussi fonction que je manque souvent lors de la conversion d'anciennes données en une nouvelle:

string ansi2utf8( const string& s )
{
   USES_CONVERSION;
   _acp = CP_ACP;
   wchar_t* pw = A2W( s.c_str() );

   _acp = CP_UTF8;
   return W2A( pw );
}

mais s'il vous plaît noter que ces macro utilisent fortement la pile - ne pas utiliser pour les boucles ou les boucles récursives pour la même fonction - après avoir utilisé W2A ou A2W macro - mieux de retourner ASAP, donc la pile sera libérée de la conversion temporaire.

1
répondu TarmoPikaro 2015-10-26 21:06:51

string s = "おはよう"; est une erreur.

vous devez utiliser wstring directement:

wstring ws = L"おはよう";
-1
répondu Andreas Bonini 2014-11-05 15:53:35

utilisez ce code pour convertir votre chaîne en wstring

std::wstring string2wString(const std::string& s){
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

int main(){
    std::wstring str="your string";
    std::wstring wStr=string2wString(str);
    return 0;
}
-2
répondu jaguar 2015-04-08 11:48:38