|
Hi All,
I am using below code to convert CString to char* and again back to CString. I am using 3rd party code which takes char* only.
const size_t newsizew = (str.GetLength()+1)*2;
char *nstringw = new char[newsizew];
size_t convertedCharsw = 0;
wcstombs_s(&convertedCharsw, nstringw, newsizew, str.GetBuffer(), newsizew /*_TRUNCATE*/ );
AfxMessageBox(CString(CA2T(nstringw)));
The conversion is working fine when content of str is in english. But this is not working properly when str is in other language.
Can anyone suggest me how to make it work even for other languages.
Thanks in advance.
|
|
|
|
|
To convert wide strings to char or multi-byte without loss of information, the wide string must only contain characters from a specific known character set / code page.
When using the wcstombs() conversion function, you must first set the locale to those used by the input string and restore it after conversion (see setlocale()[^]). The default locale is 'C' which is not language specific (English).
Another method is using WideCharToMultiByte()[^] where the code page can be specified:
int nCP = 1252; int nSize = ::WideCharToMultiByte(nCP, 0, str.GetString(), -1, NULL, 0, NULL, NULL);
char *nstringw = new char[nSize];
::WideCharToMultiByte(nCP, 0, str.GetString(), -1, nstringw, nSize, NULL, NULL);
If the code page of the input string is the same as for the current thread, you can use conversions provided by the CStringT class. This should do the job in most cases:
CStringA strA(str.GetString());
CStringW strW(strA.GetString());
|
|
|
|
|
Thanks for your reply. I am able to convert successfully using WideCharToMultiByte function. But I am facing the same problem when I use CStringA strA(str.GetStrng()) for conversion, even when I use SetLocale() function. Can you please help me out in this.
modified 21-Nov-12 5:49am.
|
|
|
|
|
Sorry for my late answer. I overlooked your reply.
The CStringT class constructors and assignment operators accepting the LPCSTR and LPCWSTR types will convert the string if it does not match (when assigning LPCWSTR to a CStringA object it is converted to ANSI and when assigning LPCSTR to a CStringW object it is converted to Unicode). The conversion is internally performed using WideCharToMultiByte() and MultiByteToWideChar() with code page CP_THREAD_ACP (when using Visual Studio 2003 and later; with older versions or manually set preprocessor definition _CONVERSION_DONT_USE_THREAD_LOCALE , CP_ACP is used). See the ATL/MFC source files cstringt.h and atlconv.h if you are interested in how the conversions are performed.
If you are not calling SetThreadLocale() within your app, the thread will use the system locale.
If the results from using WideCharToMultiByte() and CStringT constructors are different, you have passed a code page number that differs from the default code page of the used locale.
So you may post your settings here or check it yourself:
- The code page passed to
WideCharToMultiByte() - The code page used by the
CStringT class
To get the code page used by the CStringT class use this code snippet (assuming CP_THREAD_ACP is used):
int nCP = ::GetACP();
LCID nLCID = ::GetThreadLocale();
TCHAR szACP[7];
if (::GetLocaleInfo(nLCID, LOCALE_IDEFAULTANSICODEPAGE, szACP, 7) != 0)
nCP = _tstoi(szACP);
Now compare nCP with the value passed to WideCharToMultiByte() .
All these different locales and code pages may be confusing. So I will sum up the settings that may effect your conversions:
- The system locale including its default ANSI code page
- The user's locale including its default ANSI code page
- The thread's locale including its default ANSI code page
- The code page used by the
CStringT class - The code page passed to conversion functions in your code
|
|
|
|