Ответы:
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?