ฉันสามารถแปลงstd::string
ไปLPCSTR
? นอกจากนี้วิธีการที่ฉันสามารถแปลงstd::string
ไปLPWSTR
?
ฉันสับสนกับสิ่งเหล่านี้LPCSTR
LPSTR
LPWSTR
และLPCWSTR
.
เป็นLPWSTR
และLPCWSTR
เหมือนกันหรือไม่?
ฉันสามารถแปลงstd::string
ไปLPCSTR
? นอกจากนี้วิธีการที่ฉันสามารถแปลงstd::string
ไปLPWSTR
?
ฉันสับสนกับสิ่งเหล่านี้LPCSTR
LPSTR
LPWSTR
และLPCWSTR
.
เป็นLPWSTR
และLPCWSTR
เหมือนกันหรือไม่?
คำตอบ:
str.c_str()
ให้คุณconst char *
ซึ่งเป็นLPCSTR
(Long Pointer to Constant STRing) - หมายความว่าเป็นตัวชี้ไปยัง0
สตริงอักขระที่สิ้นสุด W
หมายถึงสตริงกว้าง (ประกอบด้วยwchar_t
แทนchar
)
โทรc_str()
เพื่อรับ a 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 (ยาว) ของชื่อ - เป็นการระงับจาก Windows 16 บิต
นี่คือ typedefs ที่ Microsoft กำหนดซึ่งสอดคล้องกับ:
LPCSTR: ตัวชี้ไปยังสตริง const ที่สิ้นสุดด้วย null ของ char
LPSTR: ตัวชี้ไปยังสตริงอักขระที่สิ้นสุดด้วย null ของchar
(โดยมากบัฟเฟอร์จะถูกส่งผ่านและใช้เป็นพารามิเตอร์ 'เอาต์พุต')
LPCWSTR: ตัวชี้ไปยังสตริงที่สิ้นสุดด้วย null ของ const 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 :: สตริง str; LPCSTR lpcstr = str.c_str ();
การแปลงเป็นเรื่องง่าย:
std::string myString;
LPCSTR lpMyString = myString.c_str();
สิ่งหนึ่งที่ต้องระวังคือ c_str ไม่ส่งคืนสำเนา myString แต่เป็นเพียงตัวชี้ไปยังสตริงอักขระที่ std :: string wraps หากคุณต้องการ / ต้องการสำเนาคุณจะต้องทำด้วยตัวเองโดยใช้ strcpy
วิธีที่ง่ายที่สุดในการแปลง a std::string
เป็น a LPWSTR
อยู่ในความคิดของฉัน:
std::string
ไปstd::vector<wchar_t>
wchar_t
ในเวกเตอร์std::vector<wchar_t>
มี ctor เทมเพลตซึ่งจะใช้ตัวทำซ้ำสองตัวเช่นstd::string.begin()
และตัวทำ.end()
ซ้ำ สิ่งนี้จะแปลงถ่านแต่ละตัวเป็น a wchar_t
แม้ว่า ใช้ได้เฉพาะในกรณีที่std::string
มี ASCII หรือ Latin-1 เนื่องจากค่า Unicode มีลักษณะคล้ายกับค่า Latin-1 หากมี CP1252 หรืออักขระจากการเข้ารหัสอื่น ๆ จะมีความซับซ้อนมากขึ้น จากนั้นคุณจะต้องแปลงอักขระ
std::wstring
?
std::string myString("SomeValue");
LPSTR lpSTR = const_cast<char*>(myString.c_str());
myStringเป็นสตริงอินพุตและlpSTRคือLPSTRเทียบเท่า