如何将std :: string转换为LPCSTR?
如何将std::string
转换为LPCSTR
? 另外,我怎样才能将std::string
转换为LPWSTR
?
我完全和这些LPCSTR
LPSTR
LPWSTR
和LPCWSTR
混淆了。
LPWSTR
和LPCWSTR
是一样的吗?
str.c_str()
给你一个const char *
,它是一个LPCSTR
(Long Pointer to Constant STRing) – 意味着它是一个指向0
结束string的指针。 W
表示宽string(由wchar_t
而不是char
)。
调用c_str()
从std::string
获取const char *
( LPCSTR
)。
这一切都在名称:
LPSTR
– (长)指向string的指针 – char *
LPCSTR
– (长)指向常量string的指针 – const char *
LPWSTR
– (长)指向Unicode(宽)string的指针 – wchar_t *
LPCWSTR
– (长)指向常量的Unicode(宽)string – const wchar_t *
LPTSTR
– (长)指向TCHAR的指针(如果定义了UNICODE,则为Unicode,否则为ANSI)string – TCHAR *
LPCTSTR
– (长)指向常量TCHARstring的指针 – const TCHAR *
你可以忽略L(长)部分的名字 – 这是从16位Windows的保留。
这些是Microsoft定义的typedef,它们对应于:
LPCSTR:指向以char
结尾的const char
string的指针
LPSTR:char的空string指针(通常是一个缓冲区被传递并用作'输出'参数)
LPCWSTR:指向const wchar_t
空终止string的指针
LPWSTR:指向wchar_t
空终止string的指针(通常缓冲区被传递并用作'输出'参数)
将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
实例拥有,并且只有在string被修改或销毁之后才有效。
将std::string
转换为LPWSTR
比较复杂。 想要一个LPWSTR
意味着你需要一个可修改的缓冲区,你也需要确定你知道什么字符编码 std::string
正在使用。 如果std::string
使用系统默认编码(假设是windows,这里)包含一个string,那么您可以find所需的宽字符缓冲区的长度,并使用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
你可以改变它指向的string的内容。 使用LPCWSTR
你不能改变它指向的string的内容。
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
只是一个指向原始string的指针。 您不应该使用上面的示例从函数返回它。 为了不临时LPWSTR
你应该在堆上原始string的副本。 检查下面的示例:
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 }
Charles Bailey给出的MultiByteToWideChar
答案是正确的。 因为LPCWSTR
只是const WCHAR*
一个typedef, widestr
在示例代码中可以使用widestr
,在任何需要LPWSTR
地方或者预期LPCWSTR
地方。
一个小的调整将是使用std::vector<WCHAR>
而不是手动pipe理的数组:
// 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
另外,如果你需要使用宽string开始,你可以使用std::wstring
而不是std::string
。 如果你想使用Windows TCHAR
types,你可以使用std::basic_string<TCHAR>
。 从std::wstring
转换为LPCWSTR
或从std::basic_string<TCHAR>
为LPCTSTR
只是调用c_str
。 在ANSI和UTF-16字符之间进行切换时, MultiByteToWideChar
(及其逆WideCharToMultiByte
)进入图片。
转换很简单:
std::string myString; LPCSTR lpMyString = myString.c_str();
需要注意的一点是,c_str不会返回myString的副本,而只是一个指向std :: string换行的string的指针。 如果你想/需要一个副本,你需要使用strcpy自己创build一个。
转换很简单:
std :: string str; LPCSTR lpcstr = str.c_str();
在我看来,将std::string
转换为LPWSTR
的最简单的方法是:
- 将
std::string
转换为std::vector<wchar_t>
- 获取向量中第一个
wchar_t
的地址。
std::vector<wchar_t>
有一个模板化的ctor,它需要两个迭代器,比如std::string.begin()
和.end()
迭代器。 不过,这会将每个字符转换为wchar_t
。 这只有在std::string
包含ASCII或Latin-1时才有效,因为Unicode值与Latin-1值相似。 如果它包含CP1252或任何其他编码的字符,则更为复杂。 您将需要转换字符。