convertire c ++ da LPCTSTR a const char *

Ho questo problema in MSVC2008 MFC. Sto usando unicode. Ho un prototipo di funzione:

MyFunction(const char *) 

e lo sto chiamando:

 MyfunFunction(LPCTSTR wChar). 

errore: imansible convertire il parametro 1 da ‘LPCTSTR’ a ‘const char *’

Come risolverlo?

Poiché utilizzi MFC, puoi facilmente consentire a CString di eseguire una conversione automatica da char a TCHAR :

 MyFunction(CString(wChar)); 

Funziona se la tua stringa originale è basata su char o wchar_t .

Modifica: Sembra che la mia risposta originale fosse opposta a quella richiesta. Facilmente risolto:

 MyFunction(CStringA(wChar)); 

CStringA è una versione di CString che contiene specificamente caratteri char , non TCHAR . C’è anche un CStringW che contiene wchar_t .

LPCTSTR è un puntatore a const TCHAR e TCHAR è WCHAR e WCHAR è molto probabilmente wchar_t . Rendi la tua funzione sempre const wchar_t* se puoi, o crea manualmente un buffer const char* , copia il contenuto e passa quello.

Quando UNICODE è definito per un progetto MSVC, LPCTSTR viene definito come const wchar_t * ; semplicemente cambiando la firma della funzione non funzionerà perché qualunque codice all’interno della funzione sta usando il parametro di input si aspetta un const char * .

Ti suggerirei di lasciare la firma della funzione da solo; chiama invece una funzione di conversione come WideCharToMultiByte per convertire la stringa prima di chiamare la tua funzione. Se la tua funzione viene chiamata più volte ed è troppo noioso per aggiungere la conversione prima di ogni chiamata, crea un overload MyFunction(const wchar_t *wChar) . Questo può quindi eseguire la conversione e chiamare la versione originale con il risultato.

Questo potrebbe non essere completamente in argomento, ma ho scritto un paio di funzioni di helper generiche per il mio framework wmain proposto, quindi forse sono utili per qualcuno.

Assicurati di chiamare std::setlocale(LC_CTYPE, ""); nel tuo main() prima di fare qualsiasi cosa filata!

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

È ansible fornire sovraccarichi "fittizi":

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

Ora, se hai un LPCTSTR x , puoi sempre chiamare get_locale_string(x).c_str() per ottenere una stringa di char .


Se sei curioso, ecco il resto del framework:

 #include  std::vector parse_args_from_char_to_wchar(int argc, char const * const argv[]) { assert(argc > 0); std::vector 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; } 

Ora main() - il tuo nuovo punto di ingresso è sempre int wmain(const std::vector args) :

 #ifdef WIN32 #include  extern "C" int main() { std::setlocale(LC_CTYPE, ""); int argc; wchar_t * const * const argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); return wmain(std::vector(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::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