Si tengo un UTF-8 std::string
, ¿cómo lo convierto en un UTF-16 std::wstring
? En realidad, quiero comparar dos palabras en persa.Cómo convertir UTF-8 std :: string a UTF-16 std :: wstring?
Respuesta
Aquí hay algo de código. Solo se ha probado ligeramente y es probable que haya algunas mejoras. Llame a esta función para convertir una cadena UTF-8 a una cadena WT UTF-16. Si cree que la cadena de entrada no es UTF-8, arrojará una excepción, de lo contrario, devuelve la cadena equivalente UTF-16.
std::wstring utf8_to_utf16(const std::string& utf8)
{
std::vector<unsigned long> unicode;
size_t i = 0;
while (i < utf8.size())
{
unsigned long uni;
size_t todo;
bool error = false;
unsigned char ch = utf8[i++];
if (ch <= 0x7F)
{
uni = ch;
todo = 0;
}
else if (ch <= 0xBF)
{
throw std::logic_error("not a UTF-8 string");
}
else if (ch <= 0xDF)
{
uni = ch&0x1F;
todo = 1;
}
else if (ch <= 0xEF)
{
uni = ch&0x0F;
todo = 2;
}
else if (ch <= 0xF7)
{
uni = ch&0x07;
todo = 3;
}
else
{
throw std::logic_error("not a UTF-8 string");
}
for (size_t j = 0; j < todo; ++j)
{
if (i == utf8.size())
throw std::logic_error("not a UTF-8 string");
unsigned char ch = utf8[i++];
if (ch < 0x80 || ch > 0xBF)
throw std::logic_error("not a UTF-8 string");
uni <<= 6;
uni += ch & 0x3F;
}
if (uni >= 0xD800 && uni <= 0xDFFF)
throw std::logic_error("not a UTF-8 string");
if (uni > 0x10FFFF)
throw std::logic_error("not a UTF-8 string");
unicode.push_back(uni);
}
std::wstring utf16;
for (size_t i = 0; i < unicode.size(); ++i)
{
unsigned long uni = unicode[i];
if (uni <= 0xFFFF)
{
utf16 += (wchar_t)uni;
}
else
{
uni -= 0x10000;
utf16 += (wchar_t)((uni >> 10) + 0xD800);
utf16 += (wchar_t)((uni & 0x3FF) + 0xDC00);
}
}
return utf16;
}
gracias! ¡gracias! funcionó ... No puedo creerlo :) gracias por tu tiempo john – aliakbarian
Realmente me alegro de que haya ayudado. Realmente solo se trata de hacer la pregunta correcta. Hay mucho conocimiento en este foro, pero los novatos a menudo no pueden acceder a ese conocimiento porque no saben qué preguntar. – john
¡gracias de nuevo! :-) – aliakbarian
Hay algunos relevantes Q & A here y here que vale la pena leer.
Básicamente, necesita convertir la cadena a un formato común; mi preferencia es siempre convertir a UTF-8, pero su kilometraje puede ser cauteloso.
Ha habido un montón de software escrito para hacer la conversión - la conversión hacia delante es straigth y se puede escribir en pocas horas - sin embargo, por qué no pick up something already done such as the UTF-8 CPP
Si solo tiene Windows: http://msdn.microsoft.com/en-us/library/dd319072(v=VS.85).aspx. De lo contrario, use una biblioteca portátil. –
Esta página también parece útil: http://www.codeproject.com/KB/string/UtfConverter.aspx
En la sección de comentarios de esa página, también hay algunas sugerencias interesantes para esta tarea como:
// Get en ASCII std::string from anywhere
std::string sLogLevelA = "Hello ASCII-world!";
std::wstringstream ws;
ws << sLogLevelA.c_str();
std::wstring sLogLevel = ws.str();
O
// To std::string:
str.assign(ws.begin(), ws.end());
// To std::wstring
ws.assign(str.begin(), str.end());
Aunque no estoy seguro de la validez de estos enfoques ...
Esta es la forma en que lo hace con C++ 11:
std::string str = "your string in utf8";
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>> converter;
std::wstring wstr = converter.from_bytes(str);
Y estos son los encabezados que necesita:
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
Un ejemplo más completo disponible aquí: http://en.cppreference.com/w/cpp/locale/wstring_convert/from_bytes
¡Excelente respuesta, gracias! ... pero sigue el ejemplo en cppreference.com. 'wchar_t' no es un tipo de 16 bits en sistemas operativos que no sean Windows. Necesitas usar 'char16_t' en su lugar. –
@CrisLuengo gracias! Actualicé la respuesta para usar 'char16_t' en su lugar. –
No funciona con g ++ 6.2 o clang ++ 3.8 en lubuntu 16.04 –
- 1. Cómo convertir CString y :: std :: string :: std :: wstring entre sí?
- 2. Convertir CString a std :: wstring
- 3. convertir int a std :: string
- 4. convertir std :: string a basic_ostream?
- 5. Cómo convertir std :: string a LPCSTR?
- 6. Cómo convertir std :: string a const char *?
- 7. Cómo convertir QString a std :: string?
- 8. cómo convertir std :: string a QString
- 9. Cómo convertir std :: string a NSString?
- 10. Cómo convertir std :: wstring a tipo numérico (int, long, float)?
- 11. Cómo convertir System :: String^en std :: string?
- 12. std :: wstring length
- 13. Convertir std :: string en QString
- 14. convertir std :: wstring a const * char en C++
- 15. ¿Cómo inicializar e imprimir una std :: wstring?
- 16. std :: string :: longitud() vs. std :: string :: size()
- 17. xcode std :: wcout con wchar_t o std :: wstring!
- 18. Convertir flotador para std :: string en C++
- 19. SWIG: Cómo ajustar std :: string & (std :: string pasado por referencia)
- 20. ¿Cómo convierto wchar_t * a std :: string? .?
- 21. Cómo convertir caracteres sin signo * a std :: string en C++?
- 22. Cómo convertir std :: string a LPCWSTR en C++ (Unicode)
- 23. Convierta UTF8 a UTF16 con iconv
- 24. no se puede convertir de 'std :: string' a 'LPSTR'
- 25. Rendimiento std :: strstr vs std :: string :: encontrar
- 26. Conversión de std :: string a bool
- 27. std :: vector <std::string> crash
- 28. Conversión de std :: wstring a QString lanza error de vinculador
- 29. Cómo convertir un std :: list ordenado de std :: pair a un std :: map
- 30. ¿Cómo pasar una std :: string a glShaderSource?
Ver http://stackoverflow.com/questions/148403/utf8-to-from-wide-char-conversion-in-stl entre otros. –
posible duplicado de [¿cómo puedo comparar cadena utf8 como palabras persas en C++?] (Http://stackoverflow.com/questions/7141417/how-can-i-compare-utf8-string-such-as-persian- palabras-en-c) o [esto] (http://stackoverflow.com/questions/7141260/compare-stdwstring-and-stdstring). –