Câu trả lời:
str.c_str()
mang đến cho bạn một const char *
, mà là một LPCSTR
(Long Con trỏ trỏ tới chuỗi liên tục) - phương tiện rằng đó là một con trỏ đến một 0
chuỗi chấm dứt của nhân vật. W
có nghĩa là chuỗi rộng (bao gồm wchar_t
thay vì char
).
Gọi c_str()
để lấy dấu const char *
( LPCSTR
) từ a std::string
.
Đó là tất cả trong tên:
LPSTR
- (dài) con trỏ tới chuỗi - char *
LPCSTR
- (dài) con trỏ đến chuỗi hằng số - const char *
LPWSTR
- (dài) con trỏ tới chuỗi Unicode (rộng) - wchar_t *
LPCWSTR
- (dài) con trỏ đến chuỗi Unicode (rộng) không đổi - const wchar_t *
LPTSTR
- (dài) con trỏ tới TCHAR (Unicode nếu UNICODE được xác định, ANSI nếu không) chuỗi - TCHAR *
LPCTSTR
- (dài) con trỏ đến chuỗi TCHAR không đổi - const TCHAR *
Bạn có thể bỏ qua phần L (dài) của tên - đó là phần giữ lại từ Windows 16-bit.
Đây là các typedef do Microsoft xác định tương ứng với:
LPCSTR: con trỏ đến chuỗi const bị kết thúc bằng null của char
LPSTR: con trỏ đến chuỗi ký tự kết thúc bằng null của char
(thường một bộ đệm được truyền và sử dụng làm tham số 'đầu ra')
LPCWSTR: con trỏ đến chuỗi kết thúc bằng rỗng của const wchar_t
LPWSTR: con trỏ đến chuỗi kết thúc bằng null của wchar_t
(thường một bộ đệm được truyền và sử dụng làm tham số 'đầu ra')
Để "chuyển đổi" a std::string
thành LPCSTR phụ thuộc vào ngữ cảnh chính xác nhưng thông thường gọi .c_str()
là đủ.
Những công việc này.
void TakesString(LPCSTR param);
void f(const std::string& param)
{
TakesString(param.c_str());
}
Lưu ý rằng bạn không nên cố gắng làm điều gì đó như thế này.
LPCSTR GetString()
{
std::string tmp("temporary");
return tmp.c_str();
}
Bộ đệm được trả về .c_str()
thuộc sở hữu của std::string
phiên bản và sẽ chỉ có hiệu lực cho đến khi chuỗi được sửa đổi hoặc phá hủy tiếp theo.
Để chuyển đổi a std::string
thành a LPWSTR
phức tạp hơn. Muốn một LPWSTR
ngụ ý rằng bạn cần một bộ đệm sửa đổi và bạn cũng cần phải chắc chắn rằng bạn hiểu những gì mã hóa ký tự sự std::string
đang sử dụng. Nếu std::string
chứa một chuỗi sử dụng mã hóa mặc định của hệ thống (giả sử là cửa sổ, tại đây), thì bạn có thể tìm độ dài của bộ đệm ký tự rộng được yêu cầu và thực hiện chuyển mã bằng cách sử dụng MultiByteToWideChar
(hàm Win32 API).
ví dụ
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;
}
Sử dụng, LPWSTR
bạn có thể thay đổi nội dung của chuỗi mà nó trỏ đến. Sử dụng, LPCWSTR
bạn không thể thay đổi nội dung của chuỗi nơi nó trỏ đến.
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
chỉ là một con trỏ đến chuỗi gốc. Bạn không nên trả lại nó từ chức năng bằng cách sử dụng mẫu trên. Để không tạm thời, LPWSTR
bạn nên tạo một bản sao của chuỗi gốc trên heap. Kiểm tra mẫu bên dưới:
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
}
Câu MultiByteToWideChar
trả lời mà Charles Bailey đưa ra là một trong những chính xác. Bởi vì LPCWSTR
chỉ là một định dạng choconst WCHAR*
, widestr
trong mã ví dụ, có thể được sử dụng ở bất cứ nơi nào LPWSTR
mong đợi a hoặc nơi a LPCWSTR
được mong đợi.
Một điều chỉnh nhỏ sẽ được sử dụng std::vector<WCHAR>
thay vì một mảng được quản lý thủ công:
// 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
Ngoài ra, nếu bạn cần làm việc với chuỗi rộng để bắt đầu, bạn có thể sử dụng std::wstring
thay thế std::string
. Nếu bạn muốn làm việc với TCHAR
loại Windows , bạn có thể sử dụng std::basic_string<TCHAR>
. Chuyển đổi từ std::wstring
sang LPCWSTR
hoặc từ std::basic_string<TCHAR>
đến LPCTSTR
chỉ là một vấn đề của cuộc gọi c_str
. Đó là khi bạn thay đổi giữa các ký tự ANSI và UTF-16 MultiByteToWideChar
(và nghịch đảo của nó WideCharToMultiByte
) xuất hiện trong hình ảnh.
Chuyển đổi rất đơn giản:
std::string myString;
LPCSTR lpMyString = myString.c_str();
Một điều cần cẩn thận ở đây là c_str không trả về một bản sao của myString, mà chỉ là một con trỏ đến chuỗi ký tự std :: string kết thúc. Nếu bạn muốn / cần một bản sao, bạn sẽ cần tự tạo một bản sao bằng cách sử dụng strcpy.
Theo ý kiến của tôi, cách dễ nhất để chuyển đổi a std::string
thành a LPWSTR
:
std::string
đến mộtstd::vector<wchar_t>
wchar_t
trong vector.std::vector<wchar_t>
có một ctor mẫu sẽ sử dụng hai trình vòng lặp, chẳng hạn như trình vòng lặp std::string.begin()
và .end()
. Tuy nhiên, điều này sẽ chuyển đổi mỗi ký tự thành a wchar_t
. Điều đó chỉ hợp lệ nếu std::string
chứa ASCII hoặc Latin-1, do cách các giá trị Unicode giống với các giá trị Latin-1. Nếu nó chứa CP1252 hoặc các ký tự từ bất kỳ bảng mã nào khác, thì nó phức tạp hơn. Sau đó, bạn sẽ cần chuyển đổi các ký tự.
std::wstring
?