As the title states I have a simple char that retrieves a full path name of a file I am looking for and I need to convert it to const wchar_t. How can I achieve this? Here is an example of the code:
int main()
{
char filename[] = "poc.png";
char fullFilename[MAX_PATH];
GetFullPathName(filename, MAX_PATH, fullFilename, nullptr);
const wchar_t *path = fullFilename;
}
As you can see I am trying to get the filename to convert but I couldn't find a way to do so. What would be the most simple solution to this?
Your code doesn't show any need to convert between char and wchar_t. Most likely you don't actually need to convert the character types. If you want to use the wchar_t-friendly GetFullPathNameW, then just use wchar_t instead of char.
int main()
{
wchar_t fullFilename[MAX_PATH];
GetFullPathNameW(L"poc.png", MAX_PATH, fullFilename, nullptr);
const wchar_t *path = fullFilename;
return 0;
}
If you really do need to convert between wchar_t-based C-style strings and char-based C-style strings, then you can use the APIs MultiByteToWideChar and WideCharToMultiByte.
Related
I have a string in char* format and would like to convert it to wchar_t*, to pass to a Windows function.
Does this little function help?
#include <cstdlib>
int mbstowcs(wchar_t *out, const char *in, size_t size);
Also see the C++ reference
If you don't want to link against the C runtime library, use the MultiByteToWideChar API call, e.g:
const size_t WCHARBUF = 100;
const char szSource[] = "HELLO";
wchar_t wszDest[WCHARBUF];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSource, -1, wszDest, WCHARBUF);
the Windows SDK specifies 2 functions in kernel32.lib for converting strings from and to a wide character set. those are MultiByteToWideChar() and WideCharToMultiByte().
please note that, unlike the function name suggest, the string does not necessarily use a multi-byte character set, but can be a simple ANSI string. alse note that those functions understand UTF-7 and UTF-8 as a multi-byte character set. the wide char character set is always UTF-16.
schnaader's answer use the conversion defined by the current C locale, this one uses the C++ locale interface (who said that it was simple?)
std::wstring widen(std::string const& s, std::locale loc)
{
std::char_traits<wchar_t>::state_type state = { 0 };
typedef std::codecvt<wchar_t, char, std::char_traits<wchar_t>::state_type >
ConverterFacet;
ConverterFacet const& converter(std::use_facet<ConverterFacet>(loc));
char const* nextToRead = s.data();
wchar_t buffer[BUFSIZ];
wchar_t* nextToWrite;
std::codecvt_base::result result;
std::wstring wresult;
while ((result
= converter.in
(state,
nextToRead, s.data()+s.size(), nextToRead,
buffer, buffer+sizeof(buffer)/sizeof(*buffer), nextToWrite))
== std::codecvt_base::partial)
{
wresult.append(buffer, nextToWrite);
}
if (result == std::codecvt_base::error) {
throw std::runtime_error("Encoding error");
}
wresult.append(buffer, nextToWrite);
return wresult;
}
I am trying to convert previous code to VS 2010. The code I am trying to convert is mentioned below. The function addCommand is defined like
addCommand(const ACHAR * cmdGroupName, const ACHAR * cmdGlobalName, const ACHAR * cmdLocalName, Adesk::Int32 commandFlags, AcRxFunctionPtr FunctionAddr,AcEdUIContext *UIContext=NULL, int fcode=-1, HINSTANCE hResourceHandle=NULL, AcEdCommand** cmdPtrRet=NULL)
The third required argument is of type ACHAR. The function is called in the following way.
char cmdLocRes[65];
// If idLocal is not -1, it's treated as an ID for
// a string stored in the resources.
if (idLocal != -1) {
// Load strings from the string table and register the command.
::LoadString(_hdllInstance, idLocal, cmdLocRes, 64);
acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLocRes, cmdFlags, cmdProc);
My problem is that the variable cmdLocRes is of type char but the argument needs to be of type ACHAR.
How can I convert the same ?
ACHAR is a typedef (made by Autodesk in file AdAChar.h) of wchar_t. So the question is how to convert a char to wchar_t.
In a wider context this problem is because of the existence of unicode. Linux and Windows programmers normally discuss it without understanding each other. As I do not understand it, too, I cannot explain it. There are threads for the eager beaver: What's "wrong" with C++ wchar_t and wstrings? What are some alternatives to wide characters?
The folling might give you an idea how to convert it.
// Convert char to wchar_t
char cmdLocRes[65];
// Remark: Make sure cmdLocRes contains elements!
cmdLocRes[0] = 'A';
cmdLocRes[1] = '\0';
// Get a wstringstream
std::wstringstream str;
// Write the char array to the wstringstream
str << cmdLocRes;
// Get a wstring from the wstringstream
std::wstring wstr = str.str();
// Get a wchar_t from the wstring
const wchar_t *chr1 = wstr.c_str();
const ACHAR *chr2 = wstr.c_str(); // We see that wchar_t == ACHAR!
Better think of using wchar_t cmdLocRes[65] instead of char cmdLocRes[65]!
Sorry for the code style, but this text field is another great example for how not to do it. It took me longer to try to format the code block (and please look at it!!!) than to write the answer. Jesus!!!
How do I convert CString into const char *? I have tried everything found on the internet but I still cant convert them.
Please help.
Thank you.
CString casts to const char * directly
CString temp;
temp = "Wow";
const char * foo = (LPCSTR) temp;
printf("%s", foo);
will print 'foo'
Newer version of MFC also support the GetString() method:
CString temp;
temp = "Wow";
const char * foo = temp.GetString();
printf("%s", foo);
Short answer: Use the CT2CA macro (see ATL and MFC String Conversion Macros). This will work regardless of your project's 'Character Set' setting.
Long answer:
If you have the UNICODE preprocessor symbol defined (i.e., if TCHAR is wchar_t), use the CT2CA or CW2CA macro.
If you don't (i.e., if TCHAR is char), CString already has an operator to convert to char const* implicitly (see CSimpleStringT::operator PCXSTR).
If your application is not Unicode, you can simple typecast to const char *. Use the GetBuffer() method if you need a char * that you can modify.
If your application is Unicode and you really want a char *, then you'll need to convert it. (You can use functions like MultiByteToWideChar().)
I know it's late, but I couldn't use the marked-as-answer solution. I search all over the internet and nothing worked for me. I muscled through it to get a solution:
char * convertToCharArr(CString str) {
int x = 0;
string s = "";
while (x < str.GetLength()) {
char c = str.GetAt(x++);
s += c;
}
char * output = (char *)calloc(str.GetLength() + 1, sizeof(char));
memcpy(output, s.c_str(), str.GetLength() + 1);
return output;
}
First : define char *inputString; in your_file.h
Second : define in yourFile.cpp :
CString MyString;
MyString = "Place here whatever you want";
inputString = new char[MyString.GetLength()];
inputString = MyString.GetBuffer(MyString.GetLength());
The last two sentences convert a CString variable to a char*; but be carefull, with CString you can hold millons of charcteres but with char* no. You have to define the size of your char* varible.
I have a string in char* format and would like to convert it to wchar_t*, to pass to a Windows function.
Does this little function help?
#include <cstdlib>
int mbstowcs(wchar_t *out, const char *in, size_t size);
Also see the C++ reference
If you don't want to link against the C runtime library, use the MultiByteToWideChar API call, e.g:
const size_t WCHARBUF = 100;
const char szSource[] = "HELLO";
wchar_t wszDest[WCHARBUF];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSource, -1, wszDest, WCHARBUF);
the Windows SDK specifies 2 functions in kernel32.lib for converting strings from and to a wide character set. those are MultiByteToWideChar() and WideCharToMultiByte().
please note that, unlike the function name suggest, the string does not necessarily use a multi-byte character set, but can be a simple ANSI string. alse note that those functions understand UTF-7 and UTF-8 as a multi-byte character set. the wide char character set is always UTF-16.
schnaader's answer use the conversion defined by the current C locale, this one uses the C++ locale interface (who said that it was simple?)
std::wstring widen(std::string const& s, std::locale loc)
{
std::char_traits<wchar_t>::state_type state = { 0 };
typedef std::codecvt<wchar_t, char, std::char_traits<wchar_t>::state_type >
ConverterFacet;
ConverterFacet const& converter(std::use_facet<ConverterFacet>(loc));
char const* nextToRead = s.data();
wchar_t buffer[BUFSIZ];
wchar_t* nextToWrite;
std::codecvt_base::result result;
std::wstring wresult;
while ((result
= converter.in
(state,
nextToRead, s.data()+s.size(), nextToRead,
buffer, buffer+sizeof(buffer)/sizeof(*buffer), nextToWrite))
== std::codecvt_base::partial)
{
wresult.append(buffer, nextToWrite);
}
if (result == std::codecvt_base::error) {
throw std::runtime_error("Encoding error");
}
wresult.append(buffer, nextToWrite);
return wresult;
}
Is there any method?
My computer is AMD64.
::std::string str;
BOOL loadU(const wchar_t* lpszPathName, int flag = 0);
When I used:
loadU(&str);
the VS2005 compiler says:
Error 7 error C2664:: cannot convert parameter 1 from 'std::string *__w64 ' to 'const wchar_t *'
How can I do it?
First convert it to std::wstring:
std::wstring widestr = std::wstring(str.begin(), str.end());
Then get the C string:
const wchar_t* widecstr = widestr.c_str();
This only works for ASCII strings, but it will not work if the underlying string is UTF-8 encoded. Using a conversion routine like MultiByteToWideChar() ensures that this scenario is handled properly.
If you have a std::wstring object, you can call c_str() on it to get a wchar_t*:
std::wstring name( L"Steve Nash" );
const wchar_t* szName = name.c_str();
Since you are operating on a narrow string, however, you would first need to widen it. There are various options here; one is to use Windows' built-in MultiByteToWideChar routine. That will give you an LPWSTR, which is equivalent to wchar_t*.
You can use the ATL text conversion macros to convert a narrow (char) string to a wide (wchar_t) one. For example, to convert a std::string:
#include <atlconv.h>
...
std::string str = "Hello, world!";
CA2W pszWide(str.c_str());
loadU(pszWide);
You can also specify a code page, so if your std::string contains UTF-8 chars you can use:
CA2W pszWide(str.c_str(), CP_UTF8);
Very useful but Windows only.
If you are on Linux/Unix have a look at mbstowcs() and wcstombs() defined in GNU C (from ISO C 90).
mbs stand for "Multi Bytes String" and is basically the usual zero terminated C string.
wcs stand for Wide Char String and is an array of wchar_t.
For more background details on wide chars have a look at glibc documentation here.
Need to pass a wchar_t string to a function and first be able to create the string from a literal string concantenated with an integer variable.
The original string looks like this, where 4 is the physical drive number, but I want that to be changeable to match whatever drive number I want to pass to the function
auto TargetDrive = L"\\\\.\\PhysicalDrive4";
The following works
int a = 4;
std::string stddrivestring = "\\\\.\\PhysicalDrive" + to_string(a);
std::wstring widedrivestring = std::wstring(stddrivestring.begin(), stddrivestring.end());
const wchar_t* TargetDrive = widedrivestring.c_str();