Як я можу перетворити std::string
в LPCSTR
? Крім того , як я можу перетворити std::string
в LPWSTR
?
Я цілком плутаюсь із цими LPCSTR
LPSTR
LPWSTR
та LPCWSTR
.
Це LPWSTR
і LPCWSTR
те саме?
Як я можу перетворити std::string
в LPCSTR
? Крім того , як я можу перетворити std::string
в LPWSTR
?
Я цілком плутаюсь із цими LPCSTR
LPSTR
LPWSTR
та LPCWSTR
.
Це LPWSTR
і LPCWSTR
те саме?
Відповіді:
str.c_str()
дає вам const char *
, що є LPCSTR
(Довгий покажчик на постійне STRING) - означає, що це вказівник на 0
завершений рядок символів. W
означає широкий рядок (складається із wchar_t
замість char
).
Зателефонуйте, c_str()
щоб отримати const char *
( LPCSTR
) від а std::string
.
Все в назві:
LPSTR
- (довгий) вказівник на рядок - char *
LPCSTR
- (довгий) вказівник на постійний рядок - const char *
LPWSTR
- (довгий) вказівник на рядок Unicode (широкий) - wchar_t *
LPCWSTR
- (довгий) вказівник на постійний рядок Unicode (широкий) - const wchar_t *
LPTSTR
- (довгий) вказівник на TCHAR (Unicode, якщо визначено UNICODE, ANSI, якщо ні) - TCHAR *
LPCTSTR
- (довгий) вказівник на постійний рядок TCHAR - const TCHAR *
Ви можете ігнорувати L (довгу) частину імен - це захоплення з 16-бітної Windows.
Це визначені Microsoft типівdef, які відповідають:
LPCSTR: вказівник на нульовий завершений рядок const char
LPSTR: вказівник на нульовий завершений рядок char char
(часто буфер передається і використовується як параметр 'output')
LPCWSTR: вказівник на нульовий завершений рядок const wchar_t
LPWSTR: вказівник на нульовий завершений рядок wchar_t
(часто буфер передається і використовується як параметр 'output')
"Конвертувати" a std::string
в LPCSTR залежить від конкретного контексту, але зазвичай дзвінка .c_str()
достатньо.
Це працює.
void TakesString(LPCSTR param);
void f(const std::string& param)
{
TakesString(param.c_str());
}
Зверніть увагу, що ви не повинні намагатися зробити щось подібне.
LPCSTR GetString()
{
std::string tmp("temporary");
return tmp.c_str();
}
Буфер, що повертається, .c_str()
належить std::string
екземпляру і буде дійсним лише до наступного змінення або знищення рядка.
Перетворити a std::string
в a LPWSTR
складніше. Хотіти LPWSTR
означає , що вам потрібно змінюваний буфер , і ви також повинні бути впевнені , що ви розумієте , що кодування символівstd::string
використовується. Якщо std::string
містить рядок, що використовує системне кодування за замовчуванням (якщо припустити, тут, тут), то ви можете знайти довжину необхідного буфера з широким символом та виконати перекодування за допомогою MultiByteToWideChar
(API Win32 API).
напр
void f(const std:string& instr)
{
// Assumes std::string is encoded in the current Windows ANSI codepage
int bufferlen = ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), NULL, 0);
if (bufferlen == 0)
{
// Something went wrong. Perhaps, check GetLastError() and log.
return;
}
// Allocate new LPWSTR - must deallocate it later
LPWSTR widestr = new WCHAR[bufferlen + 1];
::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), widestr, bufferlen);
// Ensure wide string is null terminated
widestr[bufferlen] = 0;
// Do something with widestr
delete[] widestr;
}
Використовуючи LPWSTR
ви можете змінити вміст рядка, на який він вказує. Використовуючи LPCWSTR
не вдалося змінити вміст рядка, на який він вказує.
std::string s = SOME_STRING;
// get temporary LPSTR (not really safe)
LPSTR pst = &s[0];
// get temporary LPCSTR (pretty safe)
LPCSTR pcstr = s.c_str();
// convert to std::wstring
std::wstring ws;
ws.assign( s.begin(), s.end() );
// get temporary LPWSTR (not really safe)
LPWSTR pwst = &ws[0];
// get temporary LPCWSTR (pretty safe)
LPCWSTR pcwstr = ws.c_str();
LPWSTR
є лише вказівником на початковий рядок. Ви не повинні повертати його з функції за допомогою наведеного вище зразка. Щоб отримати не тимчасовий характер, LPWSTR
вам слід зробити копію оригінального рядка на купі. Перевірте зразок нижче:
LPWSTR ConvertToLPWSTR( const std::string& s )
{
LPWSTR ws = new wchar_t[s.size()+1]; // +1 for zero at the end
copy( s.begin(), s.end(), ws );
ws[s.size()] = 0; // zero at the end
return ws;
}
void f()
{
std::string s = SOME_STRING;
LPWSTR ws = ConvertToLPWSTR( s );
// some actions
delete[] ws; // caller responsible for deletion
}
MultiByteToWideChar
Відповідь , що Чарльз Бейлі дав правильну один. Оскільки LPCWSTR
це лише typedef для const WCHAR*
, widestr
у прикладі коду його можна використовувати там, де LPWSTR
очікується a або де LPCWSTR
очікується a .
Одним незначним настроєм було б використовувати std::vector<WCHAR>
замість масиву, керованого вручну:
// using vector, buffer is deallocated when function ends
std::vector<WCHAR> widestr(bufferlen + 1);
::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), &widestr[0], bufferlen);
// Ensure wide string is null terminated
widestr[bufferlen] = 0;
// no need to delete; handled by vector
Крім того, якщо для початку вам потрібно працювати з широкими рядками, ви можете використовувати std::wstring
замість std::string
. Якщо ви хочете працювати з TCHAR
типом Windows , ви можете використовувати std::basic_string<TCHAR>
. Перетворення std::wstring
в LPCWSTR
або з std::basic_string<TCHAR>
на LPCTSTR
це просто питання виклику c_str
. Коли ви змінюєтесь між символами ANSI та UTF-16, це MultiByteToWideChar
(і його зворотна сторона WideCharToMultiByte
) входить у зображення.
Перетворення просте:
std::string myString;
LPCSTR lpMyString = myString.c_str();
Тут слід бути обережним, що c_str не повертає копію myString, а лише вказівник на рядок символів, який std :: string обгортає. Якщо ви хочете / потребуєте копії, вам потрібно зробити її самостійно, використовуючи strcpy.
На мою думку, найпростіший спосіб перетворити std::string
на a LPWSTR
:
std::string
на аstd::vector<wchar_t>
wchar_t
у векторі.std::vector<wchar_t>
має шаблонний ctor, який буде приймати два ітератори, такі як std::string.begin()
і .end()
ітератори. Це wchar_t
, однак, перетворить кожну таблицю в a . Це справедливо лише в тому випадку, якщо вони std::string
містять ASCII або Latin-1, завдяки тому, що значення Unicode нагадують значення Latin-1. Якщо він містить CP1252 або символи будь-якого іншого кодування, це складніше. Потім вам потрібно буде перетворити символи.
std::wstring
?