How to Convert Std::String to Lpcwstr in C++ (Unicode)

String to LPCWSTR in c++

If std::string source is English or some Latin languages then conversion to std::wstring can be done with simple copy (as shown in Miles Budnek's answer). But in general you have to use MultiByteToWideChar

std::wstring get_utf16(const std::string &str, int codepage)
{
if (str.empty()) return std::wstring();
int sz = MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), 0, 0);
std::wstring res(sz, 0);
MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), &res[0], sz);
return res;
}

You have to know the codepage used to make the source string. You can use GetACP() to find the codepage for user computer. If source string is UTF8 then use CP_UTF8 for codepage.

Converting string to LPWSTR

You may want to use Unicode UTF-16 strings in modern Windows applications when dealing with Win32 APIs: the std::wstring class (based on wchar_t) is OK for that with Visual C++.

Then, you can wrap the Win32 C API PathStripToRoot() in some C++ code, using convenient string classes instead of raw C-like string buffers.

Consider the following commented code as an example:

// Set Unicode mode
#define UNICODE
#define _UNICODE

// Windows SDK Headers
#include <Windows.h> // Win32 Platform SDK
#include <Shlwapi.h> // For PathStripToRoot()
#include <Strsafe.h> // For StringCchCopy()

// Standard C++ Headers
#include <exception> // For std::exception
#include <iostream> // For console output
#include <stdexcept> // For std::invalid_argument, std::runtime_error
#include <string> // For std::wstring

// For using PathStripToRoot()
#pragma comment(lib, "Shlwapi.lib")


// C++ wrapper around PathStripToRoot() Win32 API
std::wstring RootFromPath(const std::wstring& path)
{
// Buffer for PathStripToRoot()
wchar_t pathBuffer[MAX_PATH];

// Copy the input string into the buffer.
// Beware of buffer overruns!
HRESULT hr = ::StringCchCopy(pathBuffer, // dest
_countof(pathBuffer), // dest size
path.c_str()); // source
if (hr == STRSAFE_E_INSUFFICIENT_BUFFER)
{
// Copy failed due to insufficient buffer space.
// May accept this case or throw an exception
// based on the context...
// In this case, I just throw here.
throw std::invalid_argument("RootFromPath() - Path string too long.");
}
if (hr != S_OK)
{
throw std::runtime_error("RootFromPath() - StringCchCopy failed.");
}


// Call the Win32 C API using the raw C buffer
if (! ::PathStripToRoot(pathBuffer))
{
// No valid drive letter was found.
// Return an empty string
return std::wstring();
}

// Return a std::wstring with the buffer content
return std::wstring(pathBuffer);
}


// Test
int main()
{
try
{
const std::wstring path = L"C:\\Path1\\Path2";
const std::wstring root = RootFromPath(path);

std::wcout << "The content of the path before is:\t" << path << std::endl;
std::wcout << "RootFromPath() returned: \t" << root << std::endl;
}
catch(const std::exception& ex)
{
std::cerr << "\n*** ERROR: " << ex.what() << std::endl;
}
}

Compiled from command line:

C:\Temp\CppTests>cl /EHsc /W4 /nologo TestPathStripToRoot.cpp

Output:

C:\Temp\CppTests>TestPathStripToRoot.exe
The content of the path before is: C:\Path1\Path2
RootFromPath() returned: C:\

On that particular point of your question:

Well for one the MSDN documation says I need LPTSTR variable, but
Visual Studios says I need LPWSTR.

LPTSTR is a typedef equivalent to TCHAR*.

LPWSTR is a typedef equivalent to WCHAR*, i.e. wchar_t*.

TCHAR is a placeholder for a character type, that can be expanded to char or wchar_t, depending if you are in ANSI/MBCS or Unicode build mode.

Since VS2005, Visual Studio has been using Unicode builds as default.

So, unless you are maintaining an old legacy app that must use ANSI/MBCS, just use Unicode in modern Win32 applications. In this case, you can directly use wchar_t-based strings with Win32 APIs, without bothering with the old obsolete TCHAR-model.

Note that you can still have std::strings (which are char-based) in your code, e.g. to represent Unicode UTF-8 text. And you can convert between UTF-8 (char/std::string) and UTF-16 (wchar_t/std::wstring) at the Win32 API boundaries.

For that purpose, you can use some convenient RAII wrappers to raw Win32 MultiByteToWideChar() and WideCharToMultiByte() APIs.

How to convert std::string to LPCSTR?

str.c_str() gives you a const char *, which is an LPCSTR (Long Pointer to Constant STRing) -- means that it's a pointer to a 0 terminated string of characters. W means wide string (composed of wchar_t instead of char).

How to convert std::wstring to LPCTSTR in C++?

Simply use the c_str function of std::w/string.

See here:

http://www.cplusplus.com/reference/string/string/c_str/

std::wstring somePath(L"....\\bin\\javaw.exe");

if (!CreateProcess(somePath.c_str(),
cmdline, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
0, // Set handle inheritance to FALSE.
CREATE_NO_WINDOW, // ON VISTA/WIN7, THIS CREATES NO WINDOW
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi)) // Pointer to PROCESS_INFORMATION structure.
{
printf("CreateProcess failed\n");
return 0;
}

std::string to LPCTSTR

Your problem here is the fact that LPCTSTR is resolved to wchar_t* or char* based on whether your build supports unicode (unicode flag set or not).

To explicitly call the char* version, call CreateDirectoryA().

Converting a string to LPCWSTR for CreateFile() to address a serial port

You can either use std::wstring and std::wcin, std::wcout to perform input directly in "unicode strings", or you can look into Microsoft's conversion functions.

If you go for the 1st option (recommended), you still need to use the c_str() function to gain access to a LPCWSTR value (pointer to const wchar_t).

Sample solution (also not use of CreateFileW syntax, to prevent issues with UNICODE macro):

#include <iostream>    
#include <windows.h>
#include <string>

int main()
{
std::wstring comNum;
std::wcout << L"\n\nEnter the port (ex: COM20): ";
std::wcin >> comNum;
std::wstring comPrefix = L"\\\\.\\";
std::wstring comID = comPrefix+comNum;

HANDLE hSerial;

hSerial = CreateFileW( comID.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);`

return 0;
}


Related Topics



Leave a reply



Submit