Конвертировать lptstr в char * - PullRequest
15 голосов
/ 05 декабря 2008

Кто-нибудь знает, как преобразовать тип LPTSTR в char * в C ++?

Ответы [ 8 ]

11 голосов
/ 05 декабря 2008

Зависит от того, отображается ли он в Юникоде или нет. LPTSTR - это char *, если не Unicode, или w_char *, если это так.

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

7 голосов
/ 05 декабря 2008

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

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

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

USES_CONVERSION;
pBuffer = T2A(szString);

CString:

CStringA cstrText(szString);

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

6 голосов
/ 08 марта 2011

Если для параметра символов вашего компилятора установлено значение Набор символов Unicode , то LPTSTR будет интерпретироваться как wchar_t *. В этом случае требуется преобразование Unicode в многобайтовые символы.
(В 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;
}

С другой стороны, если для настройки символов вашего компилятора задано значение Multibyte, то 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

3 голосов
/ 05 декабря 2008
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);
}
0 голосов
/ 10 октября 2016

Я упустил простой пример, вот он:

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

LPCTSTR myLPCTSTR = getLPCTSTR();
TCHAR myT[500];
wcscpy(myT,myLPCTSTR);
char myC[500];
sprintf(myC, "%S", myT);
0 голосов
/ 04 февраля 2016

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

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

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

Кстати, если у вас все в порядке с потерей данных, то 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
}
0 голосов
/ 25 февраля 2014

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

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

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

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

0 голосов
/ 28 апреля 2013

без сомнения, многие (например, мы, юниксисты) будут в ужасе отшатываться от безумного шутника Microserf doublespeak - «если ваш компилятор находится в режиме Unicode, используйте LPWSTR или вставьте перед ним T», но только если это статическая строка, которая совпадает с буквой "L", или используйте T2A (), если используется ATL, но теперь она устарела, или используйте VARIANT, но не при связывании с COM / OLE "...).

«if (sizeof (TCHAR) == sizeof (char))», перечисленное на этой странице, является логической попыткой найти хорошее решение, но оно не скомпилируется - либо if-true не скомпилируется, либо if -false не будет компилироваться, в зависимости от флагов вашего компилятора (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;
}
...