La pregunta es cómo convertir wstring en cadena.
Tengo el siguiente ejemplo:
#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;
}
El resultado con la línea comentada es:
std::string = Hello
std::wstring = Hello
std::string = Hello
pero sin es solo:
std::wstring = Hello
¿Hay algo malo en el ejemplo? ¿Puedo hacer la conversión como arriba?
EDITAR
Nuevo ejemplo (teniendo en cuenta algunas respuestas) es
#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;
}
El resultado es:
std::string = Hello
std::wstring = Hello
std::stringstream = 0x860283c
por lo tanto, el flujo de cadena no se puede usar para convertir wstring en cadena.
std::wstring
? stackoverflow.com/questions/1049947/…Respuestas:
Aquí hay una solución resuelta basada en las otras sugerencias:
Esto generalmente funcionará para Linux, pero creará problemas en Windows.
fuente
std::setlocale(LC_ALL, "");
realmente necesario?std::wcout.imbue(locale)
debería hacer el trabajo, y tiene la ventaja de que no cambia ningún estado global.std::wstring_convert
de C ++ 11 envuelve mucho de este ruido.*** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***
Linux en 64 bits (gcc 4.7.3). ¿Alguien más está experimentando esto?Como Cubbi señaló en uno de los comentarios,
std::wstring_convert
(C ++ 11) proporciona una solución simple y ordenada (necesita#include
<locale>
y<codecvt>
):Estaba usando una combinación de
wcstombs
tediosa asignación / desasignación de memoria antes de encontrar esto.http://en.cppreference.com/w/cpp/locale/wstring_convert
actualizar (2013.11.28)
Uno de los revestimientos puede expresarse así (Gracias Guss por tu comentario):
Las funciones del contenedor se pueden establecer de la siguiente manera: (Gracias ArmanSchwarz por tu comentario)
Nota: existe cierta controversia sobre si
string
/wstring
debería pasarse a las funciones como referencias o como literales (debido a C ++ 11 y las actualizaciones del compilador). Dejaré la decisión a la persona que implementa, pero vale la pena saberlo.Nota: Estoy usando
std::codecvt_utf8
el código anterior, pero si no está usando UTF-8, deberá cambiarlo a la codificación apropiada que está usando:http://en.cppreference.com/w/cpp/header/codecvt
fuente
std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
Solución de: http://forums.devshed.com/c-programming-42/wstring-to-string-444006.html
Tenga en cuenta que no hay conversión de juego de caracteres aquí en absoluto. Lo que esto hace es simplemente asignar cada iterado
wchar_t
a unachar
conversión truncada. Utiliza el std :: string c'tor :Como se indica en los comentarios:
-
Y tenga en cuenta que los puntos de código en el rango
0x80 - 0x9F
de Win1252 serán no trabajar. Esto incluye€
,œ
,ž
,Ÿ
, ...fuente
En lugar de incluir la configuración regional y todas esas cosas elegantes, si sabe para HECHO que su cadena es convertible, simplemente haga esto:
Ejemplo en vivo aquí
fuente
Creo que la forma oficial aún es ir por las
codecvt
facetas (necesita algún tipo de traducción local), como eno algo así, no tengo código de trabajo por ahí. Pero no estoy seguro de cuántas personas en estos días usan esa maquinaria y cuántas simplemente piden punteros a la memoria y dejan que la UCI o alguna otra biblioteca maneje los detalles sangrientos.
fuente
Hay dos problemas con el código:
La conversión en
const std::string s( ws.begin(), ws.end() );
no es necesaria para asignar correctamente los caracteres anchos a su contraparte estrecha. Lo más probable es que cada carácter ancho solo sea encasilladochar
.La solución a este problema ya está dada en la respuesta de kem e involucra la
narrow
función de lactype
faceta de la localidad .Está escribiendo resultados para ambos
std::cout
ystd::wcout
en el mismo programa. Amboscout
ywcout
están asociados con el mismo flujo (stdout
) y los resultados de usar el mismo flujo tanto como flujo orientado a bytes (como locout
hace) y un flujo orientado a ancho (como lowcout
hace) no están definidos.La mejor opción es evitar mezclar salidas estrechas y anchas en la misma secuencia (subyacente). Para
stdout
/cout
/wcout
, puede intentar cambiar la orientación destdout
cuando cambie entre salida ancha y angosta (o viceversa):fuente
Este código tiene dos formas de convertir std :: string a std :: wstring y std :: wstring a std :: string. Si niega #if definió WIN32, obtendrá el mismo resultado.
1. std :: cadena a std :: wstring
• MultiByteToWideChar WinAPI
• _mbstowcs_s_l
2. std :: wstring a std :: string
• WideCharToMultiByte WinAPI
• _wcstombs_s_l
3. En Windows necesita imprimir unicode, usando WinAPI.
• WriteConsole
4. En el programa principal.
5. Finalmente, necesita un soporte potente y completo para caracteres unicode en la consola. Recomiendo ConEmu y establecerlo como terminal predeterminado en Windows . Necesita conectar Visual Studio a ConEmu. Recuerde que el archivo exe de Visual Studio es devenv.exe
Resultado
fuente
También podría usar el método estrecho de la faceta ctype directamente:
fuente
Al momento de escribir esta respuesta, la búsqueda número uno de Google para "convertir string wstring" lo llevaría a esta página. Mi respuesta muestra cómo convertir una cadena a wstring, aunque esta NO es la pregunta real, y probablemente debería eliminar esta respuesta, pero se considera una mala forma. Es posible que desee saltar a esta respuesta de StackOverflow , que ahora está mejor clasificada que esta página.
Aquí hay una manera de combinar cadenas, wstring y constantes de cadenas mixtas para wstring. Use la clase wstringstream.
fuente
Además de solo convertir los tipos, también debe tener en cuenta el formato real de la cadena.
Al compilar para el juego de caracteres Multi-byte Visual Studio y la API Win asume UTF8 (en realidad, la codificación de Windows es Windows-28591 ).
Al compilar para Unicode Character set Visual studio y Win API asume UTF16.
Por lo tanto, debe convertir la cadena de UTF16 a UTF8 también, y no solo convertir a std :: string.
Esto será necesario cuando trabaje con formatos de varios caracteres como algunos idiomas no latinos.
La idea es decidir que
std::wstring
siempre representa UTF16 .Y
std::string
siempre representa UTF8 .El compilador no aplica esto, es más una buena política. Tenga en cuenta los prefijos de cadena que uso para definir UTF16 ( L ) y UTF8 ( u8 ).
Para convertir entre los 2 tipos, debe usar: std :: codecvt_utf8_utf16 <wchar_t>
fuente
En mi caso, tengo que usar caracteres multibyte (MBCS), y quiero usar std :: string y std :: wstring. Y no puede usar c ++ 11. Entonces uso mbstowcs y wcstombs.
Realizo la misma función con el uso de new, delete [], pero es más lento que esto.
Esto puede ayudar Cómo: Convertir entre varios tipos de cadenas
EDITAR
Sin embargo, en caso de convertir a wstring y la cadena de origen no es una cadena de alfabeto y de varios bytes, no funciona. Entonces cambio wcstombs a WideCharToMultiByte.
EDITAR para usar 'MultiByteToWideChar' en lugar de 'wcstombs'
fuente
wcstombs()
.Esta solución está inspirada en la solución de dk123 , pero utiliza una faceta codecvt dependiente de la configuración regional. El resultado está en una cadena codificada en la configuración regional en lugar de UTF-8 (si no se establece como configuración regional):
Lo estaba buscando, pero no lo encuentro. Finalmente descubrí que puedo obtener la faceta correcta al
std::locale
usar lastd::use_facet()
función con el nombre de tipo correcto. Espero que esto ayude.fuente
En caso de que alguien más esté interesado: necesitaba una clase que se pudiera usar indistintamente donde sea que se esperara
string
owstring
. La siguiente claseconvertible_string
, basado en la solución de dk123 , se puede inicializar con ya sea unastring
,char const*
,wstring
owchar_t const*
y puede ser asignado a por o implícitamente convierte en ya sea unastring
owstring
(lo que puede ser pasado a un funciones que toman tampoco).fuente
std::wstring
en la clase, que almacenarstd::string
y hacer una conversiónstd::wstring
cuando sea necesario para obtener unstd::wstring
. Porquestd::wstring
es algo más rápido questd::string
y es mejor compatible. Incluso consume más memoria questd::string
.fuente
Estoy usando a continuación para convertir wstring en cadena.
fuente
<string>
) y una definición deWideCharToMultiByte()
: ¿es eso algo envolventestd::wctomb()
?fuente