MSDN > 論壇首頁 > Visual C++ Express Edition > Convert std::string to LPCWSTR (best way in c++)
發問發問
 

已答覆Convert std::string to LPCWSTR (best way in c++)

解答

  • 2006年4月6日 下午 02:11OShah 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆

     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>.

所有回覆

  • 2006年4月6日 下午 02:11OShah 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆

     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>.

  • 2006年4月23日 下午 07:10Andrew Revvo 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     提議的解答

    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

  • 2006年4月24日 上午 11:23FabioDeSantis 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    Perfect! Thank you so much!

    "Ciao guagliò!"

  • 2006年4月24日 下午 12:18OShah 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    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.

  • 2006年4月24日 下午 02:55Andrew Revvo 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    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.

  • 2006年4月25日 下午 12:17OShah 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

     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;
    }

     

  • 2008年3月22日 下午 03:59Caesium 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    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

  • 2008年3月23日 下午 11:48Vegan Fanatic 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    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.

     

  • 2009年5月30日 下午 09:14floppy22 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    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;
    }

  • 2009年5月31日 下午 12:03nobugzMVP, 版主使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    It is simple but it is wrong.  You cannot ignore character encoding, you must use MultiByteToWideChar().

    Hans Passant.
  • 2009年6月22日 上午 10:58Anadi Kumar 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    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
  • 2009年9月16日 上午 10:250xDEAD BEEF 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    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