Làm thế nào để chuyển đổi std :: string sang LPCSTR?


111

Làm cách nào để chuyển đổi a std::stringthành LPCSTR? Ngoài ra, làm cách nào để chuyển đổi một std::stringthànhLPWSTR ?

Tôi hoàn toàn bối rối với những điều này LPCSTR LPSTR LPWSTRLPCWSTR.

LPWSTRLPCWSTRgiống nhau không?

Câu trả lời:


114

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 0chuỗi chấm dứt của nhân vật. Wcó nghĩa là chuỗi rộng (bao gồm wchar_tthay vì char).


5
Điểm kén chọn nhỏ: trên x64 LPCSTR sẽ là một con trỏ 64 bit tới một chuỗi kết thúc bằng null (hằng số).
Joel

154

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.


32

Đâ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::stringthà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::stringphiê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::stringthành a LPWSTRphức tạp hơn. Muốn một LPWSTRngụ ý 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::stringchứ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;
}

18

Sử dụng, LPWSTRbạn có thể thay đổi nội dung của chuỗi mà nó trỏ đến. Sử dụng, LPCWSTRbạ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();

LPWSTRchỉ 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, LPWSTRbạ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
}

4

Câu MultiByteToWideChartrả lời mà Charles Bailey đưa ra là một trong những chính xác. Bởi vì LPCWSTRchỉ là một định dạng choconst WCHAR* , widestrtrong mã ví dụ, có thể được sử dụng ở bất cứ nơi nào LPWSTRmong đợ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::wstringthay thế std::string. Nếu bạn muốn làm việc với TCHARloại Windows , bạn có thể sử dụng std::basic_string<TCHAR>. Chuyển đổi từ std::wstringsang LPCWSTRhoặc từ std::basic_string<TCHAR>đến LPCTSTRchỉ 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.


3

Việc chuyển đổi rất đơn giản:

std :: string str; LPCSTR lpcstr = str.c_str ();


3

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.


1

Theo ý kiến ​​của tôi, cách dễ nhất để chuyển đổi a std::stringthành a LPWSTR:

  1. Chuyển đổi std::stringđến mộtstd::vector<wchar_t>
  2. Lấy địa chỉ của cái đầu tiên wchar_ttrong 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().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::stringchứ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ự.


Tại sao không sử dụng std::wstring?
Timmmm

@Timmmm: C ++ 11 đã thắt chặt đặc điểm kỹ thuật vì việc triển khai không tận dụng được các quy tắc cũ, hôm nay điều đó sẽ ổn.
MSalters

1
std::string myString("SomeValue");
LPSTR lpSTR = const_cast<char*>(myString.c_str());

myString là chuỗi đầu vào và lpSTRchuỗi tương đương LPSTR .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.