Ответы:
str.c_str()
дает вам const char *
, что является LPCSTR
(Длинный указатель на постоянную строку) - означает, что это указатель на 0
завершенную строку символов. W
означает широкую строку (составленную из wchar_t
вместо char
).
Позвоните, c_str()
чтобы получить const char *
( LPCSTR
) от a 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 typedef, которые соответствуют:
LPCSTR: указатель на константную строку с завершающим нулем char
LPSTR: указатель на строку символов с завершающим нулем char
(часто передается буфер и используется как параметр вывода)
LPCWSTR: указатель на строку константы с завершающим нулем wchar_t
LPWSTR: указатель на строку с завершающим нулем wchar_t
(часто передается буфер и используется как параметр вывода)
«Преобразование» 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
содержит строку с использованием системной кодировки по умолчанию (здесь предполагается Windows), то вы можете найти длину требуемого буфера широких символов и выполнить перекодирование с помощью MultiByteToWideChar
(функции 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
ожидается или где LPCWSTR
ожидается.
Одна небольшая поправка заключается в использовании 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.
На мой взгляд, самый простой способ преобразовать a std::string
в a LPWSTR
:
std::string
в аstd::vector<wchar_t>
wchar_t
в векторе.std::vector<wchar_t>
имеет шаблонный CTOR , который будет принимать два итератора, как, например , std::string.begin()
и .end()
итераторы. wchar_t
Тем не менее, это преобразует каждый символ в . Это допустимо, только если std::string
содержит ASCII или Latin-1 из-за того, что значения Unicode похожи на значения Latin-1. Если он содержит CP1252 или символы из любой другой кодировки, все сложнее. Затем вам нужно будет преобразовать символы.
std::wstring
?