Microsoft Developer Network > Página principal de foros > Visual C++ Express Edition > Convert std::string to LPCWSTR (best way in c++)
Formular una preguntaFormular una pregunta
 

RespondidaConvert std::string to LPCWSTR (best way in c++)

Respuestas

  • jueves, 06 de abril de 2006 14:11OShah Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respondida

     FabioDeSantis wrote:

    How can I convert an std::string to a LPCWSTR? What is the best way to do it in C++?

    Instead of using a std::string, use a std::wstring (also called a std::basic_string<wchar_t>).

    I get the feeling you want to pass a std::string type to a Win32 API. Those APIs don't take LPCWSTRs (or even LPCSTRs), they take a LPCTSTR (long pointer to a tchar-string). In this case, your question should have been: "How do I convert a std::string to a LPCTSTR?"

    Instead of using a std::string use a std::basic_string<TCHAR>.

Todas las respuestas

  • jueves, 06 de abril de 2006 14:11OShah Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respondida

     FabioDeSantis wrote:

    How can I convert an std::string to a LPCWSTR? What is the best way to do it in C++?

    Instead of using a std::string, use a std::wstring (also called a std::basic_string<wchar_t>).

    I get the feeling you want to pass a std::string type to a Win32 API. Those APIs don't take LPCWSTRs (or even LPCSTRs), they take a LPCTSTR (long pointer to a tchar-string). In this case, your question should have been: "How do I convert a std::string to a LPCTSTR?"

    Instead of using a std::string use a std::basic_string<TCHAR>.

  • domingo, 23 de abril de 2006 19:10Andrew Revvo Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respuesta propuesta

    std::wstring s2ws(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;
    }

    std::string s;

    #ifdef UNICODE
    std::wstring stemp = s2ws(s); // Temporary buffer is required
    LPCWSTR result = stemp.c_str();
    #else
    LPCWSTR result = s.c_str();
    #endif

    • Propuesto como respuestaBRIGHTEST STAR miércoles, 09 de septiembre de 2009 10:39
    •  
  • lunes, 24 de abril de 2006 11:23FabioDeSantis Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    Perfect! Thank you so much!

    "Ciao guagliò!"

  • lunes, 24 de abril de 2006 12:18OShah Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    Although you can use this function to convert a ANSI string to wide characters (or if you're comfortable with C++ iostreams:


    std::wstring ts2ws(const std::basic_string<TCHAR> &s)
    {
      /* exception safe */
      std::basic_ostringstream<TCHAR> buf;
      buf << s;
      return buf.str();

    }


    ), (or if you have the CRT wcstombs), (or if you're using the secure CRT wcstombs_s), (or if you're using ATL A2W), (or if you're using MFC CString), (or if you're using .NET PtrToStringChars), (or whatever the libraries your API provides), etc etc.

    IMO, you shouldn't need to make use of these conversions at all.

    Why?

    Ideally, your strings should all be of one datatype (either all char, or all wchar_t, or all TCHAR). This promotes consistency (a vital facet of reusable architectures). Use of these conversion macros are an indication of a flaw in your design. In the best case scenario, character conversion functions represent performance bottlenecks. In the worst case scenario, they are the source of security bugs.

    If you need to make use of a library that uses one of the other character datatypes, then either rewrite all your code to be the same as that datatype (eg. instead of using string, use wstring, or a "tstring"), or rewrite that library to fit with your datatype (replace char with wchar_t / TCHAR).

    If this means you have to rewrite your entire program from scratch, then rewrite your program from scratch (if you leave it till later, it will just get harder to port). If you don't perform the upgrade, you will leave your app slower and less secure than it can be.

    One of my pet peeves occurs when I need to make use a library that doesn't use wchar_t / TCHARs. I have to waste the rest of the day / week rewriting that library to use the wide character functions. Then I end up ditching that library, when I find out out that ignorance of unicode is the least of the problems plaguing the library.

  • lunes, 24 de abril de 2006 14:55Andrew Revvo Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    I recommend make new software, using std:wstring only, because all new Microsoft systems are UNICODE internally and there is only a small count of working Windows9x systems.

    Using of TCHAR is a poor design in Windows, unfortunately, because we should create two different exe files for unicode and ansi environment.

    Using of a std::wstring is simple. There is a fastest way to convert to it from Windows API functions or use it for Windows API calling.

    For compatible conversions use this code:

    std::string ws2s(const std::wstring& s)
    {
     int len;
     int slength = (int)s.length() + 1;
     len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0);
     char* buf = new char[len];
     WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, buf, len, 0, 0);
     std::string r(buf);
     delete[] buf;
     return r;
    }

    This function and s2ws() are checked for bugs. Only one problem may be available, if you will use these functions in expressions with c_str(). You should create a local variable in some cases, because C++ may call a string destructor and destroy string object before API calling, so this API function may get a pointer to a destructed memory.

  • martes, 25 de abril de 2006 12:17OShah Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

     Andrew Revvo wrote:
    I recommend make new software, using std:wstring only, because all new Microsoft systems are UNICODE internally

    The Windows API is TCHAR, and regardless of whether it uses unicode or ansi internally, the API is the only thing you access. Therefore, if you use the Windows API, you need to access it with TCHAR.

     Andrew Revvo wrote:
    and there is only a small count of working Windows9x systems.

    For the remaining Windows9x systems, you always have the Microsoft Layer for Unicode, which allows your unicode app to run on these systems.

     Andrew Revvo wrote:
    Using of TCHAR is a poor design in Windows, unfortunately, because we should create two different exe files for unicode and ansi environment.

    Although TCHAR's primary use is cited for developing an ansi and unicode EXE, its use extends to more than just that. You can use it to create libraries that work with both unicode and ansi projects with minimal pain. Whereas with ANSI apps, you have to rewrite the entire project to convert it to unicode, with TCHAR apps, you just need to define UNICODE.

    Having said that, DLLs should be developed Petzold-Windows style (ie. have both a W entry point and A entry point).


    std::string ws2s(const std::wstring& s)
    {
     int slength = (int)s.length() + 1;
     int len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0);
     char* buf = new char[len];
     WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, buf, len, 0, 0);
     std::string r(buf); // If this throws an exception, you'll leak memory. It will be slightly easier to use a std::vector instead, which does self checking.
     delete[] buf;
     return r;
    }

     

  • sábado, 22 de marzo de 2008 15:59Caesium Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    Very helpful. In case this is any use, here's an example I developed (with help!) for a sort of reverse operation:

    #define BUFSIZE MAX_PATH

    TCHAR Buffer[BUFSIZE];

    DWORD dwRet;

    dwRet = GetCurrentDirectory(BUFSIZE, Buffer);

    std:Tongue Tiedtring strcurpath;

    #ifdef UNICODE

    size_t i;

    char *pMBBuffer = (char *)malloc( BUFSIZE );

    wcstombs_s(&i, pMBBuffer, (size_t)BUFSIZE, Buffer, (size_t)BUFSIZE );

    strcurpath = pMBBuffer;

    #else

    strcurpath = Buffer;

    #endif

  • domingo, 23 de marzo de 2008 23:48Vegan Fanatic Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    at the end of the day std:Tongue Tiedtring will do the job, you can use UTF-8 encoding if you are in need of 3rd part language support. This simplifies things to a degree, to bad the standards group was unwilling to deal with the fact that not everyone speaks C++ fluently.

     

  • sábado, 30 de mayo de 2009 21:14floppy22 Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    Perhaps a more simple way :

    std::wstring s2ws (const std::string& s)
    {
        std::wstring ws;
        ws.assign (s.begin (), s.end ());
        return ws;
    }

    ... and so

    std::string ws2s (const std::wstring& ws)
    {
        std::wstring s;
        s.assign (ws.begin (), ws.end ());
        return s;
    }

  • domingo, 31 de mayo de 2009 12:03nobugzMVP, ModeradorMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    It is simple but it is wrong.  You cannot ignore character encoding, you must use MultiByteToWideChar().

    Hans Passant.
  • lunes, 22 de junio de 2009 10:58Anadi Kumar Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    MultiByteToWideChar

    Char * to Wide char ptr
    that is
    Char *  wchar_t *

    Code:
    int len = lenOfchPtr+1;
                     wchar_t *wText = new wchar_t[len];
                     memset(wText,0,len);
                     MultiByteToWideChar(  CP_ACP, NULL,chPtr, -1, wText,len );



    Anadi Kumar, Indo-Nepal Border Jogbani, Araria BIhar, PIN-854328
  • miércoles, 16 de septiembre de 2009 10:250xDEAD BEEF Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    I suggest using TCHAR instead of wchar_t. It will be either char or wchar depending on UNICODE define.

    please pay attention to \0 in string::format!!!

     

    array<TCHAR>^ str = String::Format("<YOUR STRING HERE>\0", i)->ToCharArray();
    TCHAR *tr = new TCHAR[str->Length];
    for(int n = 0; n < str->Length; tr[n] = str[n], n++);
    handle = CreateFile(tr, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
    delete[] tr;

    Beef