我有一个LPCTSTR
,想要调用一个带std::string
参数的函数。
我需要做什么转换?
答案 0 :(得分:16)
LPCTSTR
可以是单字节字符串也可以是多字节字符串(取决于编译期间定义的UNICODE
常量),而std::string
的用户(包括您的函数) )通常用它来保存单字节字符串。
您需要进行两次转换:一次转化为LPCSTR
(非UNICODE
版),另一次转换为LPCWSTR
(UNICODE
版本)。第一个很简单:
std::string convert(LPCSTR str) {
return std::string(str);
}
第二个需要首先使用WideCharToMultiByte
将其输入参数转换为另一个编码。不要被名称吓到,结果可以是一个单字节的字符串;这取决于CodePage
参数。您必须使用代码页进行单字节编码,例如CP_ACP
。
更新:WideCharToMultiByte
示例
请注意,如果输入字符串包含目标编码代码页中不存在的字符,则在技术上不可能准确地转换为单字节编码。由于您提到它将用于文件系统功能,如果文件路径包含此类字符,则转换将不会100%准确,后续函数调用将失败。
std::string MBFromW(LPCWSTR pwsz, UINT cp) {
int cch = WideCharToMultiByte(cp, 0, pwsz, -1, 0, 0, NULL, NULL);
char* psz = new char[cch];
WideCharToMultiByte(cp, 0, pwsz, -1, psz, cch, NULL, NULL);
std::string st(psz);
delete[] psz;
return st;
}
警告经理:上面的示例来自我所处的一些代码,并不是生产级质量。一个明显的缺陷是它不是例外安全的。它也可能杀死所有漂亮的紫色独角兽。仅将其用作示例。
赤裸裸的事实是std::string
可以用于多字节编码(例如UTF8)就好了 - 你甚至可以用它来保存宽字符串,因为它只是一个二进制安全的字节数组在心里。
问题是适用于std::string
的STL函数期望其内容采用单字节编码,如果不是这样,它们将不会产生正确的结果
通过扩展,我们不知道您的std::string
参数所需的函数是什么 - 它可能期望以UTF-8编码的字符串。但是“按照惯例”,我假设它也想要一个单字节编码的字符串。
答案 1 :(得分:10)
在一行中:
std::string s = CT2A( lpctstr );
答案 2 :(得分:2)
务实的方法:
LPCTSTR input;
std::string s;
#ifdef UNICODE
std::wstring w;
w = input;
s = std::string(w.begin(), w.end()); // magic here
#else
s = input;
#endif
查看优秀背景的其他答案!
答案 3 :(得分:2)
从您的评论:“我调用的函数将采用std :: string并在调用std :: fstream :: open()时将其用作文件名”
嗯,那是错的。该函数确实应该采用tstring
(定义为typedef std::basic_string<TCHAR> tstring
)。有许多Windows文件,如果没有Unicode,其名称无法表示。例如,如果\User\<myusername\My Documents\
<myUserName>
下的所有文件都包含非ANSI字符(并且您真的不想告诉您的用户他的名字不好!)
但是一旦你改为tstring
,它就会奏效。您仍然可以获得相同的std::fstream
对象。
答案 4 :(得分:1)
LPCTSTR
是一个Windows定义,其读取类似于“指向const字符类型字符串的长指针”。我不确定T代表什么,但它与项目的字符集有关。
如果您的项目使用Unicode字符集,则此类型为const wchar_t*
,每个字符使用两个字节。如果您的项目使用多字节字符字符集,则此类型为const char*
,每个字符使用一个字节。
您项目的字符集很可能是Unicode,因此LPCTSTR
是const wchar_t*
。由于std::string
每个字符使用一个字节,因此每个字符串不能保存这两个字节。但是,std::wstring
可以。
如果您需要将const wchar_t*
转换为const char*
以允许将其分配给字符串,则可以使用wcstombs
等函数执行此操作。如果您在项目中包含ATL(特别是atlconv.h
),它会提供宏来更轻松地执行此操作:
USES_CONVERSION;
const wchar_t* = L"Wide string";
std::string str = W2A(value);
答案 5 :(得分:1)
这段代码应该从LPWSTR转换为char * / std :: string
LPWSTR input = L"whatever";
int cSize = WideCharToMultiByte (CP_ACP, 0, input, wcslen(input), NULL, 0, NULL, NULL);
std::string output(static_cast<size_t>(cSize), '\0');
WideCharToMultiByte (CP_ACP, 0, input, wcslen(input),
reinterpret_cast<char*>(&output[0]), cSize, NULL, NULL);
并且此代码段应该从单字节std :: string转换为LPWSTR
std::string input = "whatever";
//computing wchar size:
int wSize = MultiByteToWideChar (CP_ACP, 0, (LPCSTR) input.c_str (), -1, 0, 0);
//allocating memory for wchar:
LPWSTR output = new WCHAR[wSize];
//conversion from string to LPWSTR:
MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED , (LPCSTR) input.c_str (), -1, output, wSize);
答案 6 :(得分:0)
我不知道这个solution是否可以帮到你。