2011-07-14 15 views
5

¿Cómo puedo convertir una estrecha string en una amplia string?conversión de cadena estrecha a cadena ancha

me han tratado este método:

string myName; 
getline(cin , myName); 
wstring printerName(L(myName)); // error C3861: 'L': identifier not found 
wchar_t* WprinterName = printerName.c_str(); // error C2440: 'initializing' : cannot convert from 'const wchar_t *' to 'wchar_t *' 

pero me da errores como se indica anteriormente.

¿Por qué me salen estos errores? ¿Cómo puedo solucionarlos?

¿Hay algún otro método para convertir directamente una cadena narrow en una cadena wide?

+2

es la fuente codificación UTF-8, o ASCII? – Blazes

Respuesta

7

usted debe hacer esto:

inline std::wstring convert(const std::string& as) 
{ 
      // deal with trivial case of empty string 
    if(as.empty()) return std::wstring(); 

      // determine required length of new string 
    size_t reqLength = ::MultiByteToWideChar(CP_UTF8, 0, as.c_str(), (int)as.length(), 0, 0); 

      // construct new string of required length 
    std::wstring ret(reqLength, L'\0'); 

      // convert old string to new string 
    ::MultiByteToWideChar(CP_UTF8, 0, as.c_str(), (int)as.length(), &ret[0], (int)ret.length()); 

      // return new string (compiler should optimize this away) 
    return ret; 
} 

Este espera que el std :: string sea UTF 8 (CP_UTF8), cuando tenga otra codificación, reemplace la página de códigos.

Otra forma podría ser:

inline std::wstring convert(const std::string& as) 
{ 
    wchar_t* buf = new wchar_t[as.size() * 2 + 2]; 
    swprintf(buf, L"%S", as.c_str()); 
    std::wstring rval = buf; 
    delete[] buf; 
    return rval; 
} 
+0

No he entendido el primer método. Lo que se ha hecho ? – saplingPro

+0

Convierte una std :: string estrecha (aquí UTF-8) en una std :: wstring utilizando la llamada MultiByteToWideChar Win32 API. – Christopher

+0

Se agregaron comentarios que explican qué código está haciendo en el primer método. – ravenspoint

3

Encontré this mientras buscaba en Google el problema. He pegado el código para referencia. El autor de esta publicación es Paul McKenzie.

std::string str = "Hello"; 
std::wstring str2(str.length(), L' '); // Make room for characters 

// Copy string to wstring. 
std::copy(str.begin(), str.end(), str2.begin()); 
+0

¿Qué pasa con el que he publicado? – saplingPro

+2

@grassPro: 'L' funciona solo con cadenas de constantes como' L "Hello"; '. El segundo error es autoexplicativo, 'c_str()' devuelve 'const wchar_t *' que no se puede convertir a 'wchar_t *'. – Naveen

2

Si la fuente está codificado en ASCII, sólo puede hacer esto:

wstring printerName; 
printerName.assign(myName.begin(), myName.end()); 
+1

De lejos, la forma más sencilla. Me sorprende que esto no tenga más votos. – Bronco

1

La API de Windows proporciona rutinas para hacer esto: WideCharToMultiByte() y MultiByteToWideChar(). Sin embargo, son un dolor de usar. Cada conversión requiere dos llamadas a las rutinas y debe cuidar la asignación/liberación de la memoria y asegurarse de que las cadenas terminen correctamente. ¡Necesitas un envoltorio!

Tengo un cómodo contenedor de C++ en mi blog, here, que puede usar.

2

ATL (ediciones no expresas de Visual Studio) tiene un par de tipos de clases útiles que pueden convertir las cadenas de manera simple. Puede usar el constructor directamente, si no necesita mantener la cadena.

#include <atlbase.h> 

std::wstring wideString(L"My wide string"); 
std::string narrowString("My not-so-wide string"); 

ATL::CW2A narrow(wideString.c_str()); // narrow is a narrow string 
ATL::CA2W wide(asciiString.c_str()); // wide is a wide string 
2

Aquí hay dos funciones que se pueden utilizar: mbstowcs_s y wcstombs_s.

mbstowcs_s: Convierte una secuencia de caracteres multibyte en una secuencia correspondiente de caracteres anchos. wcstombs_s: Convierte una secuencia de caracteres anchos en una secuencia correspondiente de caracteres multibyte.

errno_t wcstombs_s(
    size_t *pReturnValue, 
    char *mbstr, 
    size_t sizeInBytes, 
    const wchar_t *wcstr, 
    size_t count 
); 

errno_t mbstowcs_s(
    size_t *pReturnValue, 
    wchar_t *wcstr, 
    size_t sizeInWords, 
    const char *mbstr, 
    size_t count 

);

Ver http://msdn.microsoft.com/en-us/library/eyktyxsx.aspx y http://msdn.microsoft.com/en-us/library/s7wzt4be.aspx.

1

La pregunta original de este hilo era: "¿Cómo puedo convertir una cuerda estrecha en una cuerda ancha?"

Sin embargo, del código de ejemplo proporcionado en la pregunta, parece que no es necesaria ninguna conversión. Por el contrario, hay un error de compilación debido a que los compiladores más recientes desaprueban algo que solía estar bien.Aquí es lo que creo que está pasando:

// wchar_t* wstr = L"A wide string";  // Error: cannot convert from 'const wchar_t *' to 'wchar_t *' 

wchar_t const* wstr = L"A wide string";    // okay 
const wchar_t* wstr_equivalent = L"A wide string"; // also okay 

El c_str() parece ser tratados de la misma como un literal, y se considera una constante (const). Podrías usar un yeso. Pero es preferible agregar const.

La mejor respuesta que he visto para convertir cadenas anchas y estrechas es usar std :: wstringstream. Y esta es una de las respuestas dadas a C++ Convert string (or char*) to wstring (or wchar_t*)

Puede convertir cualquier cosa desde y hacia cadenas y cadenas de caracteres amplias usando stringstream y wstringstream.

0

This article publicado en la edición de septiembre de MSDN Magazine 2016 se analiza la conversión en detalles utilizando las API de Win32.

Tenga en cuenta que usar MultiByteToWideChar() es much faster que usar std :: stuff en Windows.

0

Uso mbtowc():

string myName; 
wchar_t wstr[BUFFER_SIZE]; 

getline(cin , myName); 
mbtowc(wstr, myName, BUFFER_SIZE);