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

    ATL and MFC String Conversion Macros

    CString Management

以上是关于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#)

SQL 语句转换格式函数CastConvert

Can't convert the date-like value to string because it isn't known if it's a date (no ti