C++ Convert string (ou char*) en wstring (ou wchart*)
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.
int StringToWString(std::wstring &ws, const std::string &s)
{
std::wstring wsTmp(s.begin(), s.end());
ws = wsTmp;
return 0;
}
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.
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);
}
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 .
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.
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();
utilisant Boost.Paramètres régionaux:
ws = boost::locale::conv::utf_to_utf<wchar_t>(s);
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;
}
}
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;
}
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.
string s = "おはよう";
est une erreur.
vous devez utiliser wstring directement:
wstring ws = L"おはよう";
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;
}