• 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

  • 相关阅读:
    PS:图像的编辑(三)修复画笔工具
    如何知道自己电脑连接的无线网密码
    ps里“栅格化图层”有啥作用
    如何解决 ERROR Code 1101报错
    Oracle中SCOTT用户的 emp、dept、bonus、salgrade表的属性和结构
    PSCC2019以上版本如何取消等比裁剪
    distinct 多列详解
    银行取款、查询余额、交电话费功能
    银行卡系统,输入密码取钱功能
    根据周长计算不同形状图形的面积
  • 原文地址:https://www.cnblogs.com/time-is-life/p/5534481.html
Copyright © 2020-2023  润新知