C++: Having unicode console title..? - c++

When I try to set my console's title to a string that has unicode characters in it, using SetConsoleTitle(), the title displays just some garbage characters instead.
I have also tried the SetConsoleTitleW() function, but that gives me the following error:
error: cannot convert 'const char*' to 'const WCHAR*' for argument '1' to 'BOOL SetConsoleTitleW(const WCHAR*)'
Any advice?

You have to use wide string literal, that is:
SetConsoleTitleW(L"DиD");
The L, before a quote denotes, that this is a wchar_t* string.
Also, for completness I have to say, that in C++11, there are new string literal prefixes defined:
const char a[] = u8"for a UTF-8 string.";
const char_16_t b[] = u"for a UTF-16 string.";
const char_32_t c[] = U"for a UTF-32 string.";
as usual wikipedia has more detailed note about that.

It looks as if you are attempting to send UTF-8-encoded data to a function that expects UTF-16-encoded data.
You need to either convert the string literal to UTF-16 (i.e. WCHAR*) before passing it to the function, or create the literal as a WCHAR* literal (which I believe is done using the syntax L"DиD").

Related

Cannot convert const char* to PCWSTR after changing to Use Multi Byte Character Set

I am trying to pass a const char* to a windows SetThreadDescription() function.
int pthread_setname_np(HANDLE thread, const char* name) {
return SetThreadDescription(thread, name);
}
and I am getting an error
'HRESULT SetThreadDescription(HANDLE,PCWSTR)': cannot convert argument 2 from 'const char *' to 'PCWSTR'
Of course I've stumbled into this and checked the character set and it was already set to Use Multi-Byte Character Set. Is there a way to fix this?
edit: add properties
#someprogrammerdude provided the answer in a comment:
The SetThreadDescription function doesn't seem to exist in an "ASCII" (non-wide character) version. You need to convert the string to wide-character string and use that converted string in the call.

Converting string to wchar_t (wide character) C++ [duplicate]

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();

Opening directory function

This is a basic understanding concepts related question.
Working using: Embarcadero C++ Builder
What is the difference between:
opendir("C:\\XYZ")
and
String file = "C:\\XYZ";
opendir(file);
Aren't both strings?
The first one works but the sexond gives me error:
E2034 Cannot convert Unicode String to ' const char*'
In a case where I take input from the user I can only pass a string. How do i pass the whole path?
first one is a const char*, second one is a std::string. The opendir function accepts only const char* in your case and thus cannot convert std::string to const char* on its own. you can get the function to work by opendir(file.c_str()); .
No. A String is not a char array. opendir needs a char array.
opendir() expects an 8bit narrow const char* as input. When you pass a narrow literal to opendir(), you are passing it a const char[], which implicitly degrades to const char*, and all is fine.
String is System::String, which is a typedef for System::UnicodeString, which is Embarcadero's UTF-16 encoded string class (similar to std::wstring, but with different semantics). When you pass a String to opendir(), you get a conversion error.
To pass a String value to opendir() (or any other function that expects char*), you need to first convert it to a System::AnsiString, and then use AnsiString::c_str() to get a char* from it, eg:
String file = "C:\\XYZ";
opendir(AnsiString(file).c_str());

convert string to _T in cpp

I want to convert string or char* to the _T but not able to do.
if i write
_tcscpy(cmdline,_T ("hello world"));
it works perfectly, but if i write
char* msg="hello world";
_tcscpy(cmdline,_T (msg));
it shows an error like: error C2065: 'Lmsg' : undeclared identifier
Please give me a solution.
Thanx in advance.
_T is a macro, defined as (if UNICODE is defined):
#define _T(a) L ## a
which can work only with string-literals. So when you write _T("hi") it becomes L"hi" which is valid, as expected. But when you write _T(msg) it becomes Lmsg which is an undefined identifier, and you didn't intend that.
All you need is this function mbstowcs as:
const char* msg="hello world"; //use const char*, instead of char*
wchar_t *wmsg = new wchar_t[strlen(msg)+1]; //memory allocation
mbstowcs(wmsg, msg, strlen(msg)+1);
//then use wmsg instead of msg
_tcscpy(cmdline, wmsg);
//memory deallocation - must do to avoid memory leak!
delete []wmsg;
_T only works with string literals. All it does is turn the literal into an L"" string if the code's being compiled with Unicode support, or leave it alone otherwise.
Take a look at http://msdn.microsoft.com/en-us/library/dybsewaf(v=vs.80).aspx
You need to use mbtowcs function.
You should also look at this article.
_T is a macro that makes string literals into wide-char string literals by prepending an L before the literal in UNICODE builds.
In other words, when you write _T("Hello") it is as if you had written "Hello" on an ANSI build or L"Hello" on a UNICODE build. The type of the resulting expression is char* or wchar_t* respectively.
_T can not convert a string variable (std::string or char*) to a wchar_t* -- for this, you have to use a function like mbstowcs or MultiByteToWideChar.
Suggestion: It will be much easier for you (and in no way worse) to always make a UNICODE build and forget about _T, TCHAR and all other T-derivatives. Just use wide-character strings everywhere.
_T is not an actual type. It's a macro that prepends string literals with L so that they would be wchar_t*s instead of char*. If you need to convert a char* string to wchar_t* one at runtime, you need mbtowcs for example.
The _T modifier is just a declaration to tell the compiler that the string literal must be interpreted as a utf-16 encoding. The reason it doesn't work on the variable is because the contents of that variable have already been declared as ascii.
As already mentioned the mbstowcs function is what you need to perform the conversion of a char data into utf-16 (wide char) data.

I want to convert std::string into a const wchar_t *

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();