ฉันสามารถแปลง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::stringa 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เทียบเท่า