Преобразовать lptstr в char *

Может ли кто-нибудь узнать, как преобразовать тип LPTSTR в char * в С++?

Ответы

Ответ 1

Зависит от Юникода или нет. LPTSTR char *, если не Unicode, или w_char * если это так.

Здесь лучше обсуждается (принятый ответ стоит прочитать)

Ответ 2

Здесь много способов сделать это. MFC или ATL CString, макросы ATL или API Win32.

LPTSTR szString = _T("Testing");
char* pBuffer;

Вы можете использовать макросы ATL для преобразования:

USES_CONVERSION;
pBuffer = T2A(szString);

CString:

CStringA cstrText(szString);

или Win32 API WideCharToMultiByte, если UNICODE определен.

Ответ 3

Если для параметра Character Character установлено значение Unicode Character Set, тогда LPTSTR будет интерпретироваться как wchar_t *. В этом случае требуется преобразование символов Unicode в Multibyte.
(В Visual Studio параметр находится в Свойствах проекта\Свойства конфигурации\Общие\Набор символов)

Пример кода ниже должен дать представление:

#include <windows.h>

/* string consisting of several Asian characters */
LPTSTR wcsString = L"\u9580\u961c\u9640\u963f\u963b\u9644";
//LPTSTR wcsString = L"OnlyAsciiCharacters";

char* encode(const wchar_t* wstr, unsigned int codePage)
{
    int sizeNeeded = WideCharToMultiByte(codePage, 0, wstr, -1, NULL, 0, NULL, NULL);
    char* encodedStr = new char[sizeNeeded];
    WideCharToMultiByte(codePage, 0, wstr, -1, encodedStr, sizeNeeded, NULL, NULL);
    return encodedStr;
}

wchar_t* decode(const char* encodedStr, unsigned int codePage)
{
   int sizeNeeded = MultiByteToWideChar(codePage, 0, encodedStr, -1, NULL, 0);
   wchar_t* decodedStr = new wchar_t[sizeNeeded ];
   MultiByteToWideChar(codePage, 0, encodedStr, -1, decodedStr, sizeNeeded );
   return decodedStr;
}

int main(int argc, char* argv[])
{
   char* str = encode(wcsString, CP_UTF8); //UTF-8 encoding
   wchar_t* wstr = decode(str, CP_UTF8);
   //If the wcsString is UTF-8 encodable, then this comparison will result to true.
   //(As i remember some of the Chinese dialects cannot be UTF-8 encoded 
   bool ok = memcmp(wstr, wcsString, sizeof(wchar_t) * wcslen(wcsString)) == 0; 
   delete str;
   delete wstr;

   str = encode(wcsString, 20127); //US-ASCII (7-bit) encoding
   wstr = decode(str, 20127);
   //If there were non-ascii characters existing on wcsString, 
   //we cannot return back, since some of the data is lost
   ok = memcmp(wstr, wcsString, sizeof(wchar_t) * wcslen(wcsString)) == 0; 
   delete str;
   delete wstr;
}

С другой стороны, если для параметра "Настройка персонажа компилятора" установлено значение "Мультибайт", то LPTSTR будет интерпретироваться как char *.

В этом случае:

LPTSTR x = "test";
char* y;
y = x;

Также смотрите:

Еще одна дискуссия о преобразовании wchar_t: Как правильно использовать WideCharToMultiByte
Статья MSDN: http://msdn.microsoft.com/en-us/library/dd374130(v=vs.85).aspx
Действительные идентификаторы страницы кода: http://msdn.microsoft.com/en-us/library/dd317756(v=vs.85).aspx

Ответ 4

char * pCopy = NULL;
if (sizeof(TCHAR) == sizeof(char))
{
    size_t size = strlen(pOriginal);
    pCopy = new char[size + 1];
    strcpy(pCopy, pOriginal);
}
else
{
    size_t size = wcstombs(NULL, pOriginal, 0);
    pCopy = new char[size + 1];
    wcstombs(pCopy, pOriginal, size + 1);
}

Ответ 5

ОК, так что скажем, что вам нужно использовать Unicode. И вы используете некоторые функции, такие как LookupAccountSid, которые необходимы для вашей программы для работы, но они возвращают LPTSTR для важной информации, которую вам нужно обрабатывать как строку (по какой-либо причине - это программирование, что-то вроде этого происходит)

Теперь, если вы используете multibyte - это не будет проблемой. Но есть способ решить эту проблему. Это мой метод и, по общему признанию, неаккуратный. Но тем не менее вы должны уметь видеть, как это работает.

const std::wstring &wstring = AcctName; // AcctName being my LPTSTR string
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstring[0], (int)wstring.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);

WideCharToMultiByte(CP_UTF8, 0, & wstring[0], (int)wstring[0], &strTo[0], size_needed, NULL, NULL);

char* charUserName = new char[strTo.size() + 1];

// Set charUserName via copying
std::copy(strTo.begin(), strTo.end(), charUserName);
charUserName[strTo.size()] = '\0';

SetUPI(charUserName); // charUserName being my converted char * - 
// You don't need this last part - but this is an example of passing to method
// that takes a string

Любые вопросы просто спрашивают. Я понимаю, что это старый пост, но мне нравится публиковать сообщения для людей, которые приходят в поисках. (люди вроде меня)

Ответ 6

Я надеюсь, что это поможет кому-то, потому что мне понадобилось время, чтобы понять, как это сделать.

Прежде всего, LPTSTR имеет тип указателя и в основном эквивалентен TCHAR* (при условии, что <tchar.h> включен). Обратите внимание, что размер TCHAR зависит от типа кодировки символов. то есть, если уникод определен, TCHAR равен wchar_t, в противном случае это char.

Естественно, если вы преобразуете широкий символ в обычный char, вы можете сохранить только LSB и потерять некоторые данные. Это было как-то раздражающе для меня. поэтому я написал следующий код. Его главным преимуществом является преобразование без потери каких-либо данных.

Кстати, если вы в порядке с потерей данных, то wcstombs выполняет задание.

#include <cstring>
#include <algorithm>
#include <tchar.h>

void lptstr2str(LPTSTR tch, char* &pch) // or (TCHAR* tch, char* &pch)
{
#ifndef UNICODE
    std::memcpy(pch, tch, strlen(tch) + 1);
#else
    size_t n =
        sizeof(TCHAR) / sizeof(char)* wcsnlen(tch, std::string::npos);
    pch = new char[n + 1];
    std::memcpy(pch, tch, n + 1);
    int len = n - std::count(pch, pch + n, NULL);
    std::remove(pch, pch + n, NULL);
    pch[len] = NULL;
#endif
}

Ответ 7

Мне не хватало простого примера, вот он:

(для меня char * идентичен char [])

LPCTSTR myLPCTSTR = getLPCTSTR();
TCHAR myT[500];
wcscpy(myT,myLPCTSTR);
char myC[500];
sprintf(myC, "%S", myT);

Ответ 8

Несомненно, многие (например, us unix folk) в ужасе отшатнутся на безумном Microserf doublelespeak - "если ваш компилятор находится в режиме Unicode, используйте LPWSTR или вставите перед ним" T_ ", но только если это статическая строка, которая совпадает с" L "или использует T2A(), если используется ATL, но это устарело или используется VARIANT, но не связано с COM/OLE"...).

"if (sizeof (TCHAR) == sizeof (char))", указанный на этой странице, является логической попыткой хорошего решения, но он не будет компилироваться - либо if-true не будет компилироваться или if-false wont ', в зависимости от ваших флагов компилятора (Aaargh!). Для портативного решения с записью и записью вам нужно прибегнуть к макрокоманде UNICODE с более высоким именем. Я предлагаю эту адаптацию предыдущего кода:

string mfc_to_zstring (CString &sref)
{
    char nojoy[65536];
    char *ptr, *psin = NULL;
    string sot;
    LPCTSTR p = sref;


#if UNICODE
    if (sizeof(TCHAR) != sizeof(char))
    {
        size_t n = wcstombs(NULL, p, 0);
        if (n > 65530)
        {
            psin = new char[n + 1];
            wcstombs(psin, p, n + 1);
            ptr = psin;
        }
        else
        {
            wcstombs(nojoy, p, n + 1);
            ptr = nojoy;
        }

        sot = ptr;
        if (psin != NULL)
            delete psin;
    }
    else
        { std::cerr << "Aaargh! Microsoft horror.\n"; exit(1); }
#else
    if (sizeof(TCHAR) == sizeof(char))
    {
        const char *ptr = p;
        sot = ptr;
    }
    else
      { std::cerr << "Aaargh! You should never see this line\n"; exit(1); }
#endif

    return sot;
}