开发者

c++ convert from LPCTSTR to const char *

开发者 https://www.devze.com 2023-03-17 06:15 出处:网络
I have this problem in MSVC2008 MFC. I´m using unicode. I have a function prototype: MyFunction(const char *开发者_Go百科)

I have this problem in MSVC2008 MFC. I´m using unicode. I have a function prototype:

MyFunction(const char *开发者_Go百科)

and I'm calling it:

MyfunFunction(LPCTSTR wChar). 

error:Cannot Convert Parameter 1 From 'LPCTSTR' to 'const char *'

How to resolve it?


Since you're using MFC, you can easily let CString do an automatic conversion from char to TCHAR:

MyFunction(CString(wChar));

This works whether your original string is char or wchar_t based.

Edit: It seems my original answer was opposite of what you asked for. Easily fixed:

MyFunction(CStringA(wChar));

CStringA is a version of CString that specifically contains char characters, not TCHAR. There's also a CStringW which holds wchar_t.


LPCTSTR is a pointer to const TCHAR and TCHAR is WCHAR and WCHAR is most probably wchar_t. Make your function take const wchar_t* if you can, or manually create a const char* buffer, copy the contents, and pass that.


When UNICODE is defined for an MSVC project LPCTSTR is defined as const wchar_t *; simply changing the function signature will not work because whatever code within the function is using the input parameter expects a const char *.

I'd suggest you leave the function signature alone; instead call a conversion function such as WideCharToMultiByte to convert the string before calling your function. If your function is called several times and it is too tedious to add the conversion before every call, create an overload MyFunction(const wchar_t *wChar). This one can then perform the conversion and call the original version with the result.


This may not be totally on topic, but I wrote a couple of generic helper functions for my proposed wmain framework, so perhaps they're useful for someone.

Make sure to call std::setlocale(LC_CTYPE, ""); in your main() before doing any stringy stuff!

#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);
}

You could provide "dummy" overloads:

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

Now, if you have an LPCTSTR x, you can always call get_locale_string(x).c_str() to get a char-string.


If you're curious, here's the rest of the framework:

#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;
}

Now the main() -- your new entry point is always int wmain(const std::vector<std::wstring> 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


In this example I convert a LPCTSTR to a const char pointer and a char pointer. For this conversion you need to include windows.h and atlstr.h, I hope to help you.

// 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);
0

精彩评论

暂无评论...
验证码 换一张
取 消