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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架