Posterior a consultar con especialistas en la materia, programadores de varias ramas y maestros dimos con la respuesta al dilema y la dejamos plasmada en esta publicación.
Solución:
debes llamar MultiByteToWideChar
dos veces:
-
La primera llamada a
MultiByteToWideChar
se utiliza para encontrar el tamaño de búfer que necesita para el ancho string. Mire la documentación de Microsoft; afirma:Si la función tiene éxito y cchWideChar es 0, el valor devuelto es el tamaño requerido, en caracteres, para el búfer indicado por lpWideCharStr.
Así, para hacer
MultiByteToWideChar
darle el tamaño requerido, pasar 0 como el valor del último parámetro,cchWideChar
. también deberías pasarNULL
como el anterior,lpWideCharStr
. -
Obtenga un búfer no constante lo suficientemente grande como para acomodar el ancho string, utilizando el tamaño de búfer del paso anterior. Pase este búfer a otra llamada a
MultiByteToWideChar
. Y esta vez, el último argumento debe ser el tamaño real del búfer, no 0.
Un ejemplo esquemático:
int wchars_num = MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , -1, NULL , 0 );
wchar_t* wstr = new wchar_t[wchars_num];
MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , -1, wstr , wchars_num );
// do whatever with wstr
delete[] wstr;
Además, tenga en cuenta el uso de -1 como el cbMultiByte
argumento. Esto hará que el resultado string null-terminado, ahorrándote de tratar con ellos.
Puede probar esta solución a continuación. Probé, funciona, detecta caracteres especiales (ejemplo: º ä ç á ) y funciona en Windows XP, Windows 2000 con SP4 y posteriores, Windows 7, 8, 8.1 y 10. Usando std::wstring
en cambio new wchar_t
/ delete
reducimos los problemas con los recursos de fuga, el búfer de desbordamiento y el montón corrupto.
dwFlags
se fijó en MB_ERR_INVALID_CHARS
funciona en Windows 2000 con SP4 y posterior, Windows XP. Si este indicador no está configurado, la función elimina silenciosamente los puntos de código ilegales.
std::wstring ConvertStringToWstring(const std::string &str)
if (str.empty())
return std::wstring();
int num_chars = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), NULL, 0);
std::wstring wstrTo;
if (num_chars)
wstrTo.resize(num_chars);
if (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), &wstrTo[0], num_chars))
return wstrTo;
return std::wstring();
Pocas conversiones comunes:
#define WIN32_LEAN_AND_MEAN
#include
#include
std::string ConvertWideToANSI(const std::wstring& wstr)
int count = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
std::string str(count, 0);
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL);
return str;
std::wstring ConvertAnsiToWide(const std::string& str)
int count = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), NULL, 0);
std::wstring wstr(count, 0);
MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), &wstr[0], count);
return wstr;
std::string ConvertWideToUtf8(const std::wstring& wstr)
int count = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
std::string str(count, 0);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL);
return str;
std::wstring ConvertUtf8ToWide(const std::string& str)
int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
std::wstring wstr(count, 0);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count);
return wstr;
Sección de Reseñas y Valoraciones
Si entiendes que ha sido provechoso nuestro post, sería de mucha ayuda si lo compartes con el resto programadores de este modo contrubuyes a difundir esta información.