Convert CString to ANSI string in UNICODE projects
Posted 人最大的荣耀不在于从未失败,而在于每次失败以后都能东山再起
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Convert CString to ANSI string in UNICODE projects相关的知识,希望对你有一定的参考价值。
Convert CString to ANSI string in UNICODE projects
Quick Answer: use an intermediate CStringA.
- Normally, this is not something that should be done. *It is technically unreliable, unless you can guarantee that the source CString to be converted does not contain any 2-byte characters.
- This will work fine if you are using the English language without any special 2-byte symbols or accented letters.
- This article is for educational use, and explains how it can easily be done, without relying on the USES_CONVERSION macro with W2A, or ridiculous WideCharToMultiByte API functions.
- If you are using a language that actually requires Unicode (Asian languages, etc), or if the source CString contains any 2-byte character, this cannot be done. This is because there is no ANSI equivalent of any 2-byte character.
- It is the responsibility of the programmer to ensure that the source CString does not contain any 2-byte characters.
Use intermediate CStringA (highly recommended):
- Pros: this is the easiest to use.
- Cons: you cannot specify a code page.
CString LastNameW(L"Smith");
CStringA LastNameA(LastNameW);
FunctionForAnsi(LastNameA.GetString());
- Or an even simpler example:
CString LastNameW(L"Smith");
FunctionForAnsi(CStringA(LastNameW).GetString());
Here are some other ways that either do not work or are not recommended. I list them here to document things to avoid. What not to do.
WideCharToMultiByte API function (not recommended):
- Pros: you can specify the desired code page.
- Cons: too much code to write, test, debug.
CString LastNameW(L"Smith");
int nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)LastNameW, -1, NULL, NULL);
LPSTR lpszA = new CHAR[nLen];
WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)LastNameW, -1, lpszA, nLen);
FunctionForAnsi(lpszA);
delete[] lpszA; // free the string
W2A ATL 3.0 macros (not recommended):
- Cons: not safe inside loops.
- Cons: you cannot specify a code page.
USES_CONVERSION;
CString LastNameW(L"Smith");
FunctionForAnsi(W2A(LastNameW.GetString()));
CW2A ATL 7.0 conversion template classes (not recommended):
- There are 3 ways you can use the CW2A template class. Only one of them is the right way.
- Cons: too difficult to remember the correct usage
- Cons: too easy to use improperly.
CString LastNameW(L"Smith");
CW2A pszA(LastNameW.GetString()); // this is the right way
FunctionForAnsi(pszA);
CString LastNameW(L"Smith");
FunctionForAnsi(CW2A(LastNameW.GetString())); // improper usage, do not do this
CString LastNameW(L"Smith");
LPCSTR pszA = CW2A(LastNameW.GetString()); // improper usage, do not do this
FunctionForAnsi(pszA);
(LPCSTR)(LPCTSTR) cast:
- Do not use this!
- You cannot use (LPCSTR)(LPCTSTR) to cast a CString to LPCSTR in Unicode projects.
- It does compile, but it does not properly convert the CString to an LPCSTR.
- The resulting string will either be 0 or 1 length, or filled with garbage characters of unknown length, because the cast just changes the pointer type without any conversion.
- You end up with a CHAR* pointing to a WCHAR array, a very bad thing.
CString LastName(L"Smith");
FunctionForAnsi((LPCSTR)(LPCTSTR)LastName); // improper usage, do not to this
REF:
ATL String: What‘s wrong with the USES_CONVERSION macros? How to avoid using them?
Using MFC MBCS/Unicode Conversion Macros
以上是关于Convert CString to ANSI string in UNICODE projects的主要内容,如果未能解决你的问题,请参考以下文章
C# Tips: String Convert to byte[]
Codeforces-758D Ability To Convert
Leetcode-1028 Convert to Base -2(负二进制转换)
Convert IPv6 Address to IP numbers (C#)
Can't convert the date-like value to string because it isn't known if it's a date (no ti