【问题标题】:c++ convert from LPCTSTR to const char *c++ 从 LPCTSTR 转换为 const char *
【发布时间】:2011-09-29 02:23:39
【问题描述】:

我在 MSVC2008 MFC 中遇到了这个问题。我正在使用 unicode。我有一个函数原型:

MyFunction(const char *)

我叫它:

MyfunFunction(LPCTSTR wChar). 

错误:无法将参数 1 从 'LPCTSTR' 转换为 'const char *'

如何解决?

【问题讨论】:

  • 你在调用什么函数?你自己写的吗?它应该能够处理 Unicode 字符串吗?

标签: c++ types type-conversion


【解决方案1】:

在此示例中,我将 LPCTSTR 转换为 const char 指针和 char 指针。这个转换需要包含windows.h和atlstr.h,希望对你有所帮助。

// Required inclusions
#include <windows.h>
#include <atlstr.h>

// Code
LPCTSTR fileName = L"test.txt";
CStringA stringA(fileName);
const char* constCharP = stringA;
char* charP = const_cast<char*>(constCharP);

【讨论】:

    【解决方案2】:

    这可能不完全是主题,但我为我提议的 wmain framework 编写了几个通用帮助函数,所以它们可能对某人有用。

    在做任何棘手的事情之前,请务必在您的main() 中调用std::setlocale(LC_CTYPE, "");!

    #include <string>
    #include <vector>
    #include <clocale>
    #include <cassert>
    
    std::string get_locale_string(const std::wstring & s)
    {
      const wchar_t * cs = s.c_str();
      const size_t wn = wcsrtombs(NULL, &cs, 0, NULL);
    
      if (wn == size_t(-1))
      {
        std::cout << "Error in wcsrtombs(): " << errno << std::endl;
        return "";
      }
    
      std::vector<char> buf(wn + 1);
      const size_t wn_again = wcsrtombs(&buf[0], &cs, wn + 1, NULL);
    
      if (wn_again == size_t(-1))
      {
        std::cout << "Error in wcsrtombs(): " << errno << std::endl;
        return "";
      }
    
      assert(cs == NULL); // successful conversion
    
      return std::string(&buf[0], wn);
    }
    
    std::wstring get_wstring(const std::string & s)
    {
      const char * cs = s.c_str();
      const size_t wn = mbsrtowcs(NULL, &cs, 0, NULL);
    
      if (wn == size_t(-1))
      {
        std::cout << "Error in mbsrtowcs(): " << errno << std::endl;
        return L"";
      }
    
      std::vector<wchar_t> buf(wn + 1);
      const size_t wn_again = mbsrtowcs(&buf[0], &cs, wn + 1, NULL);
    
      if (wn_again == size_t(-1))
      {
        std::cout << "Error in mbsrtowcs(): " << errno << std::endl;
        return L"";
      }
    
      assert(cs == NULL); // successful conversion
    
      return std::wstring(&buf[0], wn);
    }
    

    您可以提供“虚拟”重载:

    inline std::string get_locale_string(const std::string & s) { return s; }
    inline std::wstring get_wstring(const std::wstring & s) { return s; }
    

    现在,如果您有LPCTSTR x,您可以随时调用get_locale_string(x).c_str() 来获取char 字符串。


    如果您好奇,以下是框架的其余部分:

    #include <vector>
    
    std::vector<std::wstring> parse_args_from_char_to_wchar(int argc, char const * const argv[])
    {
      assert(argc > 0);
    
      std::vector<std::wstring> args;
      args.reserve(argc);
    
      for (int i = 0; i < argc; ++i)
      {
        const std::wstring arg = get_wstring(argv[i]);
        if (!arg.empty()) args.push_back(std::move(arg));
      }
    
      return args;
    }
    

    现在是main()——你的新入口点总是int wmain(const std::vector&lt;std::wstring&gt; args):

    #ifdef WIN32
    
    #include <windows.h>
    
    extern "C" int main()
    {
      std::setlocale(LC_CTYPE, "");
    
      int argc;
      wchar_t * const * const argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
    
      return wmain(std::vector<std::wstring>(argv, argv + argc));
    }
    
    #else // WIN32
    
    extern "C" int main(int argc, char *argv[])
    {
      LOCALE = std::setlocale(LC_CTYPE, "");
    
      if (LOCALE == NULL)
      {
        LOCALE = std::setlocale(LC_CTYPE, "en_US.utf8");
      }
    
      if (LOCALE == NULL)
      {
        std::cout << "Failed to set any reasonable locale; not parsing command line arguments." << std::endl;
        return wmain(std::vector<std::wstring>());
      }
    
      std::cout << "Locale set to " << LOCALE << ". Your character type has "
                << 8 * sizeof(std::wstring::value_type) << " bits." << std::endl;
    
      return wmain(parse_args_from_char_to_wchar(argc, argv));
    }
    
    #endif
    

    【讨论】:

      【解决方案3】:

      由于您使用的是 MFC,您可以轻松地让 CString 自动从 char 转换为 TCHAR:

      MyFunction(CString(wChar));
      

      无论您的原始字符串是基于char 还是基于wchar_t,这都有效。

      编辑:看来我原来的答案与你的要求相反。轻松修复:

      MyFunction(CStringA(wChar));
      

      CStringA 是CString 的一个版本,它专门包含char 字符,而不是TCHAR。还有一个CStringW 包含wchar_t。

      【讨论】:

        【解决方案4】:

        当为 MSVC 项目定义 UNICODE 时,LPCTSTR 定义为 const wchar_t *;简单地更改函数签名将不起作用,因为函数中使用输入参数的任何代码都需要const char *。

        我建议你不要管函数签名;而是在调用函数之前调用转换函数(例如 WideCharToMultiByte)来转换字符串。如果您的函数被多次调用并且每次调用之前添加转换太乏味,请创建重载MyFunction(const wchar_t *wChar)。然后可以执行转换并使用结果调用原始版本。

        【讨论】:

          【解决方案5】:

          LPCTSTR 是指向const TCHAR 的指针,TCHAR 是WCHAR,WCHAR 很可能是wchar_t。如果可以的话,让你的函数使用const wchar_t*,或者手动创建一个const char* 缓冲区,复制内容并传递它。

          【讨论】:

          • 更好的是,提供从const wchar_t * 到const char *(或std::wstring 到std::string)的通用翻译函数,使用区域设置感知wcstombs 并通过它考虑所有呼叫。
          • wcstombs 用于:将 const wchar_t * 转换为 char 。我必须从 LPCTSTR(const wchar_t) 转换为 const char*。
          • @Annie: wcstombs 可以正常工作。任何接受const char * 的函数也将接受char *,它只会将后者视为const。
          • @Annie:问题出在哪里?如果函数接受const char *,它将毫无问题地接受char *。
          • Matteo:我的问题是如何将 const 宽 char 指针转换为 const 单字节 char 指针
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-31
          • 2012-01-16
          • 1970-01-01
          相关资源
          最近更新 更多