Можно также генерировать ERD от Microsoft Visual Studio 2005.
str.c_str ()
дает вам const char *
, который является LPCSTR
(длинный указатель на постоянную строку) - означает, что это указатель на завершающуюся строку символов 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.
Килобайт (КБ) равен 1024 байтам.
Kilo означает 1000.
Итак, если следовать чисто обозначениям: (65k = 65,000)! = (65KB = 66 560).
Однако, если вы говорите о памяти, вы, вероятно, всегда будете видеть KB ( даже если он записан как k).
Обычно KB = k. Это все очень запутанно .
string и будет действителен только до следующего изменения или уничтожения строки. Преобразовать std :: string
в 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
- это просто определение типа для const WCHAR *
, widestr
в примере кода может использоваться везде, где ожидается LPWSTR
или где ожидается LPCWSTR
.
Одна небольшая поправка заключается в использовании std :: vector
вместо массива, управляемого вручную:
// 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
. Если вы хотите работать с типом Windows TCHAR
, вы можете использовать std :: basic_string
. Преобразование из std :: wstring
в LPCWSTR
или от std :: basic_string
до LPCTSTR
- это просто вопрос вызова c_str
. Когда вы переключаетесь между символами ANSI и UTF-16, появляется MultiByteToWideChar
(и его обратный WideCharToMultiByte
).
Преобразование просто:
std::string myString;
LPCSTR lpMyString = myString.c_str();
Здесь следует остерегаться того, что c_str возвращает не копию myString, а просто указатель на символьную строку, которую оборачивает std :: string. Если вы хотите / вам нужна копия, вам нужно будет сделать ее самостоятельно, используя strcpy.
Преобразование простое:
std :: string str; LPCSTR lpcstr = str.c_str ();
На мой взгляд, самый простой способ преобразовать std :: string
в LPWSTR
]:
std: : строка
в std :: vector
wchar_t
в векторе. std :: vector
имеет шаблонный ctor, который будет принимать два итератора, например итераторы std :: string.begin ()
и .end ()
. Тем не менее, это преобразует каждый char в wchar_t
. Это допустимо только в том случае, если std :: string
содержит ASCII или Latin-1 из-за того, что значения Unicode напоминают значения Latin-1. Если он содержит CP1252 или символы из любой другой кодировки, все сложнее. Затем вам нужно будет преобразовать символы.