Problem with string conversion
-
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.
-
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; // Example: Windows-1252
// Get required buffer size
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:// Create a char/multi-byte string from wide string.
// Pass LPCSTR to constructor, so use casting or GetString()!
CStringA strA(str.GetString());
// Convert it back to a wide string
CStringW strW(strA.GetString()); -
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; // Example: Windows-1252
// Get required buffer size
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:// Create a char/multi-byte string from wide string.
// Pass LPCSTR to constructor, so use casting or GetString()!
CStringA strA(str.GetString());
// Convert it back to a wide string
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.
-
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.
Sorry for my late answer. I overlooked your reply. The
CStringT
class constructors and assignment operators accepting theLPCSTR
andLPCWSTR
types will convert the string if it does not match (when assigningLPCWSTR
to aCStringA
object it is converted to ANSI and when assigningLPCSTR
to aCStringW
object it is converted to Unicode). The conversion is internally performed usingWideCharToMultiByte()
andMultiByteToWideChar()
with code pageCP_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 callingSetThreadLocale()
within your app, the thread will use the system locale. If the results from usingWideCharToMultiByte()
andCStringT
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 (assumingCP_THREAD_ACP
is used):// Default ANSI code page
int nCP = ::GetACP();
// Returns same as GetSystemDefaultLCID() when SetThreadLocale() has not been called.
LCID nLCID = ::GetThreadLocale();
TCHAR szACP[7];
if (::GetLocaleInfo(nLCID, LOCALE_IDEFAULTANSICODEPAGE, szACP, 7) != 0)
nCP = _tstoi(szACP);Now compare
nCP
with the value passed toWideCharToMultiByte()
. 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
- The code page passed to