So a quick question how do I make TCHAR* (or wchar_t as its a macro) work with char*?
I am using the unicode character set.
The code that is the problem is:
TCHAR* D3DDevTypeToString(D3DDEVTYPE devType) {
switch (devType) {
case D3DDEVTYPE_HAL:
return TEXT("D3DDEVTYPE_HAL");
case D3DDEVTYPE_SW:
return TEXT("D3DDEVTYPE_SW");
case D3DDEVTYPE_REF:
return TEXT("D3DDEVTYPE_REF");
default:
return TEXT("Unknown devType");
}
}
The obvious solution is to change TCHAR* to char* but I would like to keep it as TCHAR* if possible.
Thanks.
And yes I am using the unicode character set.
Then you cannot make TCHAR compatible with char. Because if you're using UCS, then TCHAR is wchar_t. The type char is not related in any way to wchar_t. You could do some work to convert the string (using e.g. WideCharToMultiByte), but then you'd lose Unicode support.
TCHAR could be wchar_t or char, depeding upon whether the macro UNICODE is defined or not.
If the macro UNICODE is defined, then TCHAR means wchar_t. In this case, you cannot use TCHAR in place of, or with, char. It's dangerous!
If it's not defined, then TCHAR means char. In this case, you can use TCHAR in place of, or with, char. After all, they're same now.
Write a converter from UTF-16 to UTF-8 (or use the win32 API function if that's what it does). Make it generic so it can work on char*, wchar_t*, std::string, and std::wstring. Write a templated function string_cast and let the second parameter be figured out by the compiler. Override string_cast for the different combinations you will be using. Convert between TCHAR* to std::string with string_cast and then it doesn't matter how TCHAR is defined (assuming you overrode for both char and wchar_t.
Related
I'm trying to pass a process name as a TCHAR to the following void:
void GetBaseAddressByName(DWORD pID, TCHAR *pN)
By doing it like this:
GetBaseAddressByName(aProcs[i], (TCHAR*)"Process.exe");
So my question is: is what I am doing correct? Because I have tried both TEXT("Process.exe") and _T("Process.exe") with my project's Character Set both on Multi-Bite and Unicode and it just tells me that
argument of type "const char*" is incompatible with parameter of type "TCHAR*"
The short answer is no. TCHAR maps to either char or wchar_t depending on your project's Unicode/Multi-byte setting. So, in general, a cast like that is either unnecessary or incorrect. The correct way, as you said, is to use either the TEXT or _T macro. The reason you're getting an error is that you're trying to pass a const character string to a function that expects a mutable character string. The safeset way to get around the error is to copy your constant string into a local TCHAR buffer and then pass that to GetBaseAddressByName.
It is better to have a TCHAR array first, then copy into it.
#include "atlstr.h"
char const * procName = "processName.exe";
TCHAR szName [128];
_tcscpy(szName, A2T(procName));
GetBaseAddressByName(aProcs[i], szName);
As suggested by #Remy Lebeau in the comments, procName can be defined as TCHAR const * procName = TEXT("processName.exe");.
(TCHAR*)"Process.exe" is not a valid type-cast. It will "work" when the project charset is set to ANSI/MBCS, but it will produce garbage if the charset is set to Unicode.
Using TEXT("Process.exe") is the correct way to make a string literal use TCHAR characters.
GetBaseAddressByName(aProcs[i], TEXT("Process.exe"));
However, you need to change your pN parameter to const TCHAR * (or LPCTSTR) instead:
void GetBaseAddressByName(DWORD pID, const TCHAR *pN);
void GetBaseAddressByName(DWORD pID, LPCTSTR pN);
A string literal is const data, and you cannot pass a pointer-to-const-data where a pointer-to-non-const-data is expected (without casting the const away with const_cast). That is why you were still getting errors when trying to use the TEXT()/_T() macros.
You need a L, like L"Process.exe". Unicode strings are specified with L"".
That said, there is no reason to use TCHAR. Use unicode all the time, if doing Windows work only.
I'm trying to combine 2 tchar.
char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);
TCHAR* appdatapath ="C:\\Users\\"+username+"\\AppData";
But I get error error at appdatapath line. How can I combine 2 tchar? Thanks
Have a look at strcat and wcscat. You can't add char pointer with char array.
If you are on a windows machine, you can use _tcscat which will redirect to the right function to use depending on _UNICODE and _MBCS defines.
Might want to use the safe versions as well by appending _s to the function name.
As pointed in the comments, you can also use snprintf like so:
const size_t concatenated_size = 256;
char concatenated[concatenated_size];
snprintf(concatenated, concatenated_size, "C:\\Users\\%s\\AppData", username);
Since you have string literals before and after the runtime string, it is probably a better approach.
To answer the question in the title: you concatenate two TCHAR strings using the _tcscat function.
However, there are other issues in your code related to this: GetUserName expects a LPTSTR, i.e. a pointer to a buffer TCHAR characters. Furthermore, there's another TCHAR usage in
TCHAR* appdatapath ="C:\\Users\\"+username+"\\AppData";
The issue with this is that the type to which TCHAR expands changes depending on whether _UNICODE is defined. In particular, if you set it, TCHAR (eventually) expands to wchar and hence GetUserName expects a wchar_t* but you pass a char*. Another issue is that you cannot concatenate C arrays using the + operator.
I suggest to stop worrying about TCHAR in the first place and always just compile with _UNICODE defined - and use wchar throughout your code. Also, since you're using C++, just use std::wstring:
wchar username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserNameW(username, &username_len);
std::wstring appdatapath = L"C:\\Users\\";
appdatapath += username;
appdatapath += L"\\AppData";
Last but not least: your entire code can probably be replaced with a call to the SHGetSpecialFolderPath function - pass CSIDL_APPDATA to it to get the "AppData" path.
#include <tchar.h>
const size_t stringSize= 20;
TCHAR value[stringSize] = { 0 };
_tcscat_s(value, stringSize, TEXT("appendMe"));
MSDN: _tcscat_s
I am new to MFC. I am trying to do simple mfc application and I'm getting confuse in some places. For example, SetWindowText have two api, SetWindowTextA, SetWindowTextW one api takes char * and another one accepts wchar_t *.
What is the use of char * and wchar_t *?
char is used for so called ANSI family of functions (typically function name ends with A), or more commonly known as using ASCII character set.
wchar_t is used for new so called Unicode (or Wide) family of functions (typically function name ends with W), which use UTF-16 character set. It is very similar to UCS-2, but not quite it. If character requires more than 2 bytes, it will be converted into 2 composite codepoints, and this can be very confusing.
If you want to convert one to another, it is not really simple task. You will need to use something like MultiByteToWideChar, which requires knowing and providing code page for input ANSI string.
On Windows, APIs that take char * use the current code page whereas wchar_t * APIs use UTF-16. As a result, you should always use wchar_t on Windows. A recommended way to do this is to:
// Be sure to define this BEFORE including <windows.h>
#define UNICODE 1
#include <windows.h>
When UNICODE is defined, APIs like SetWindowText will be aliased to SetWindowTextW and can therefore be used safely. Without UNICODE, SetWindowText will be aliased to SetWindowTextA and therefore cannot be used without first converting to the current code page.
However, there's no good reason to use wchar_t when you are not calling Windows APIs, since its portable functionality is not useful, and its useful functionality is not portable (wchar_t is UTF-16 only on Windows, on most other platforms it is UTF-32, what a total mess.)
SetWindowTextA takes char*, which is a pointer to ANSI strings.
SetWindowTextW takes wchar_t*, which is a pointer to "wide" strings (Unicode).
SetWindowText has been defined (#define) to either of these in header Windows.h based on the type of application you are building. If you are building a UNICODE build then your code will automatically use SetWindowTextW.
SetWindowTextA is there primarily to support legacy code, which needs to be built as SBCS (Single byte character set).
char* : It means that this is a pointer to data of type char.
Example
// Regular char
char aChar = 'a';
// Pointer to char
char* aPointer = new char;
*aPointer = 'a';
// Pointer to an array of 10 chars
char* anArray = new char[ 10 ];
*anArray = 'a';
anArray[ 1 ] = 'b';
// Also a pointer to an array of 10
char[] anArray = new char[ 10 ];
*anArray = 'a';
anArray[ 1 ] = 'b';
wchar_t* : wchar_t is defined such that any locale's char encoding can be converted to a wchar_t representation where every wchar_t represents exactly one codepoint.
This question already has answers here:
What is `CString`?
(3 answers)
Closed 9 years ago.
Can someone explain me the difference and the relationship between the char * and CString?... Thanks.
There are few important differences.
char * is a pointer to char. Generally you can't say if it a single char, or a beginning of a string, and what is the length. All those things are dictated by program logic and some conventions, i.e. standard C functions, like to use const char * as inputs. You need to manage memory allocated for strings manually.
CString is a macro. Depending on your program compilation options, it can be defined to either the CStringA or CStringW class. There are differences and similarities.
The difference is that CStringAoperates with non-Unicode data (similar to char*), and CStringW is a Unicode string (similar to wchar_t*).
Both classes, however, are equivalent in the aspect of string manipulation and storage management. They are closer to the standard C++ std::string and std::wstring classes.
Apart from that, both CStringA and CStringW provide the capability to convert strings to and from Unicode form.
a CString will be an array of char and a char* will be a pointer into the array of char with which you can iterate the characters of the string.
Actually from MSDN:
CString is based on the TCHAR data type. If the symbol _UNICODE is defined for your program, TCHAR is defined as type wchar_t, a 16-bit character type; otherwise, it is defined as char, the normal 8-bit character type. Under Unicode, then, CString objects are composed of 16-bit characters. Without Unicode, they are composed of 8-bit char type.
CString is a class packed with different functionalities.. MSDN
char * is just a regular c++ data type.
CString is used mostly in MFC applications.
CString is a sequence of TCHAR-s rather then char*. The main difference is that if UNICODE is defined CString will be sequence of wchar. Actually depending on that macro CString will be tpyedef -ed either to CStringA or CStringW. Another major difference is that CString is a class while char* is simply a pointer to character.
Depending on the type of TCHAR, CString can be either CStringA or CStringW.
That said, CString is a wrapper over an array of chars, that enables you to easily treat that array of chars as a string, and operate on it in manners relevant to the string type.
For the relationship between them, here is something that illustrates it easily. You can convert between char * and CString like this:
CString str = "abc"; // const char[3] or char * to CString
and
const char * p = str.Get() // CString to const char *
A CString is a class and provides lots of functionalities that a char * doesnt. A char * is just a pointer to char or chars array.
A CString contains a buffer that is roughtly the same as a char * : LPTSTR GetBuffer( int nMinBufLength );
For the difference between LPTSTR and char * go here and here
CString is a wrapper class around a char* to provide some useful additional functions and to hide the memory allocation/deallocation from the user.
There is not much difference in performance terms so if you are using MFC classes, you might as well use a CString.
How to convert a std::wstring to a TCHAR*? std::wstring.c_str() does not work since it returns a wchar_t*.
How do I get from wchar_t* to TCHAR*, or from std::wstring to TCHAR*?
use this :
wstring str1(L"Hello world");
TCHAR * v1 = (wchar_t *)str1.c_str();
#include <atlconv.h>
TCHAR *dst = W2T(src.c_str());
Will do the right thing in ANSI or Unicode builds.
TCHAR* is defined to be wchar_t* if UNICODE is defined, otherwise it's char*. So your code might look something like this:
wchar_t* src;
TCHAR* result;
#ifdef UNICODE
result = src;
#else
//I think W2A is defined in atlbase.h, and it returns a stack-allocated var.
//If that's not OK, look at the documenation for wcstombs.
result = W2A(src);
#endif
in general this is not possible since wchar_t may not be the same size as TCHAR.
several solutions are already listed for converting between character sets. these can work if the character sets overlap for the range being converted.
I prefer to sidestep the issue entirely wherever possible and use a standard string that is defined on the TCHAR character set as follows:
typedef std::basic_string<TCHAR> tstring;
using this you now have a standard library compatible string that is also compatible with the windows TCHAR macro.
You can use:
wstring ws = L"Testing123";
string s(ws.begin(), ws.end());
// s.c_str() is what you're after
Assuming that you are operating on Windows.
If you are in Unicode build configuration, then TCHAR and wchar_t are the same thing. You might need a cast depending on whether you have /Z set for wchar_t is a type versus wchar_t is a typedef.
If you are in a multibyte build configuration, you need MultiByteToWideChar (and vica versa).