2009-07-29 37 views
93

Làm cách nào để chuyển đổi một số std::string thành LPCSTR? Ngoài ra, làm cách nào tôi có thể chuyển đổi một số std::string thành LPWSTR?Làm thế nào để chuyển đổi std :: chuỗi để LPCSTR?

Tôi hoàn toàn nhầm lẫn với những số này LPCSTRLPSTRLPWSTRLPCWSTR.

Có phải LPWSTRLPCWSTR giống nhau không?

Trả lời

91

str.c_str() cung cấp cho bạn const char *, là LPCSTR (Con trỏ dài đến cố định liên tục) - có nghĩa là đó là con trỏ đến một chuỗi ký tự bị chấm dứt 0. W nghĩa là chuỗi rộng (bao gồm wchar_t thay vì char).

+5

Điểm cầu kỳ nhỏ: trên x64 LPCSTR sẽ là một con trỏ 64 bit đến chuỗi kết thúc null (không đổi). – Joel

2

Chuyển đổi rất đơn giản:

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

138

Gọi c_str() để nhận số const char * (LPCSTR) từ số std::string.

Đó là tất cả trong tên:

LPSTR - (dài) con trỏ đến chuỗi - char *

LPCSTR - (dài) con trỏ đến liên tục chuỗi - const char *

LPWSTR - (dài) con trỏ đến Chuỗi Unicode (rộng) - wchar_t *

LPCWSTR - (dài) con trỏ đến hằng số Unicode (rộng) chuỗi - const wchar_t *

LPTSTR - (dài) con trỏ đến TCHAR (Unicode nếu UNICODE được định nghĩa, ANSI nếu không muốn nói) chuỗi - TCHAR *

LPCTSTR - (dài) con trỏ đến chuỗi TCHAR liên tục - const TCHAR *

Bạn có thể bỏ qua phần L (dài) của tên - đó là một sự lưu giữ từ Windows 16 bit.

32

Đây là Microsoft typedefs được xác định tương ứng với:

LPCSTR: con trỏ null chấm dứt chuỗi const của char

LPSTR: con trỏ null chấm dứt chuỗi char của char (thường là một bộ đệm được thông qua và sử dụng như một 'đầu ra' param)

LPCWSTR: con trỏ null chuỗi chấm dứt của const wchar_t

LPWSTR: con trỏ null t erminated chuỗi wchar_t (thường là một bộ đệm được thông qua và sử dụng như một 'đầu ra' param)

Để "chuyển đổi" một std::string đến một LPCSTR phụ thuộc vào bối cảnh chính xác nhưng thường gọi .c_str() là đủ.

Tác phẩm 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ề bởi .c_str() thuộc sở hữu của std::string dụ và sẽ chỉ có giá trị cho đến khi chuỗi được tiếp sửa đổi hoặc hủy bỏ.

Để chuyển đổi std::string thành LPWSTR phức tạp hơn. Muốn một số LPWSTR ngụ ý rằng bạn cần bộ đệm có thể sửa đổi và bạn cũng cần chắc chắn rằng bạn hiểu mã hóa ký tự đang sử dụng là gì. Nếu std::string chứa chuỗi sử dụng mã hóa mặc định của hệ thống (giả sử cửa sổ, tại đây), thì bạn có thể tìm độ dài của bộ đệm ký tự được yêu cầu và thực hiện chuyển mã bằng cách sử dụng MultiByteToWideChar (chức năng API Win32).

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; 
} 
3

Chuyển đổi rất đơn giản:

std::string myString; 

LPCSTR lpMyString = myString.c_str(); 

Một điều cần phải cẩn thận đây là c_str không trả lại một bản sao của myString, nhưng chỉ cần một con trỏ đến chuỗi ký tự mà std :: string kết thúc tốt đẹp . Nếu bạn muốn/cần một bản sao, bạn sẽ cần phải thực hiện một bản thân bằng cách sử dụng strcpy.

+0

Làm thế nào để chuyển đổi std :: String to LPWSTR ??? – Cute

1

Cách đơn giản nhất để chuyển đổi một std::string đến một LPWSTR là theo ý kiến ​​của tôi:

  1. Chuyển đổi std::string đến một std::vector<wchar_t>
  2. Đi theo địa chỉ của wchar_t đầu tiên trong vector.

std::vector<wchar_t> có một ctor templated mà sẽ mất hai vòng lặp, chẳng hạn như std::string.begin().end() lặp. Điều này sẽ chuyển đổi mỗi char thành một wchar_t, mặc dù. Điều đó chỉ hợp lệ nếu std::string chứa ASCII hoặc Latin-1, do cách giá trị Unicode giống với giá trị Latinh-1.Nếu nó chứa CP1252 hoặc các ký tự từ bất kỳ mã hóa nào khác, nó phức tạp hơn. Sau đó, bạn sẽ cần phải chuyển đổi các ký tự.

14

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 mà 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à con trỏ đến chuỗi gốc. Bạn không nên trả lại nó từ hàm bằng cách sử dụng mẫu ở trên. Để nhận được 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 
} 
4

Câu trả lời MultiByteToWideChar mà Charles Bailey đưa ra là đúng. Bởi vì LPCWSTR chỉ là một typedef cho const WCHAR*, widestr trong mã ví dụ, bạn có thể sử dụng bất kỳ nơi nào tại một dự án LPWSTR hoặc dự kiến ​​LPCWSTR.

Một tinh chỉnh nhỏ sẽ được sử dụng std::vector<WCHAR> thay vì một mảng bằng tay quản lý:

// 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 phải làm việc với chuỗi rộng để bắt đầu, bạn có thể sử dụng std::wstring thay vì std::string. Nếu bạn muốn làm việc với loại Windows TCHAR, bạn có thể sử dụng std::basic_string<TCHAR>. Chuyển đổi từ std::wstring thành LPCWSTR hoặc từ std::basic_string<TCHAR> đến LPCTSTR chỉ là vấn đề gọi c_str. Đó là khi bạn đang thay đổi giữa các ký tự ANSI và UTF-16 mà MultiByteToWideChar (và nghịch đảo của nó WideCharToMultiByte) đi vào hình ảnh.

Các vấn đề liên quan