如何在c++中将PWSTR转换为字符串?
How do I convert PWSTR to string in C++?
我有以下代码:
// Fetch Local App Data folder path.
PWSTR localAppData = (PWSTR) malloc(128);
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
// Find out the absolute path to chrome.exe
stringstream ss;
ss << localAppData << "/Google/Chrome/Application/chrome.exe";
stringstreamer的.str()
的结果是008F6788/Google/Chrome/Application/chrome.exe
,这是错误的
由于类型不兼容,我似乎无法让stringstreamer工作,strcat或wcsncat也无法工作。
我如何将这个PWSTR转换为字符串?
的趣事!
微软表示:typedef wchar_t* LPWSTR, *PWSTR;
所以让我们把这些可怕的废话从你的测试用例中去掉,丢掉C的垃圾:
// Fetch Local App Data folder path.
wchar_t* localAppData = new wchar_t[128];
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
stringstream ss;
ss << localAppData << "/Google/Chrome/Application/chrome.exe";
delete[] localAppData;
<标题> 2。警告!
这里有一个严重的缺陷
SHGetKnownFolderPath
实际上设置了你给它的指针的值,指向它分配的内存。你的代码有内存泄漏,我的最后一个代码片段微妙地错误地释放了内存。
让我们通过阅读文档来解决这个问题:
ppszPath [出]
Type: PWSTR*
当此方法返回时,包含指向指定已知文件夹路径的以空结尾的Unicode字符串的指针的地址。一旦不再需要这个资源,调用进程负责通过调用CoTaskMemFree来释放这个资源。返回的路径不包括尾随的反斜杠。例如,返回"C:Users"而不是"C:Users"。
// Fetch Local App Data folder path.
wchar_t* localAppData = 0;
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
stringstream ss;
ss << localAppData << "/Google/Chrome/Application/chrome.exe";
CoTaskMemFree(static_cast<void*>(localAppData));
现在开始表演。
<标题> 3。宽字符
你的代码的语法问题是,localAppData是一个wchar_t
,但正常的stringstream
s工作在char
。
幸运的是,有一个叫做wstringstream
的宽字符变体,它使用wchar_t
来代替。
(注意,这意味着您的文字也必须在wchar_t
之外构建,使用L
字符串文字前缀。)
最后的代码是:
// Fetch Local App Data folder path.
wchar_t* localAppData = 0;
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
wstringstream ss;
ss << localAppData << L"/Google/Chrome/Application/chrome.exe";
CoTaskMemFree(static_cast<void*>(localAppData));
标题>标题>PWSTR
是一个指向宽字符串的指针。你需要
// Fetch Local App Data folder path.
PWSTR localAppData = (PWSTR) malloc(128);
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
wstringstream ss;
ss << localAppData << L"/Google/Chrome/Application/chrome.exe";
另外,malloc
参数指示要分配的字节数,因此您分配的缓冲区只能容纳64个宽字符(包括NULL字符)。您可能需要使用malloc( 128 * sizeof(wchar_t) )
.
来自SHGetKnownFolderPath
ppszPath当此方法返回时,包含指向指定已知文件夹路径的以空结尾的Unicode字符串的指针的地址。调用进程负责通过调用
在不再需要该资源时释放该资源。CoTaskMemFree
所以你不应该为函数的最后一个参数分配任何内存。
wchar_t *localAppData = NULL;
::SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
wstringstream ss;
ss << localAppData << L"/Google/Chrome/Application/chrome.exe";
::CoTaskMemFree(localAppData);
我喜欢Praetorina的Praetorian的答案只是使用宽字符串流,但如果你想转换:
char str[128];
wcstombs(str, localAppData, 128);
还有一个函数也是相反的:
wchar_t wstr[128];
mbstowcs(wstr, "Hello World", 128);
不能将宽字符字符串"强制转换"为字符串。原因(除了2字节单位VS. 1字节单位的问题)是这种"强制转换"将是不明确的。
源编码是什么?目标编码是什么?在这种情况下,源编码可能是Unicode (shell扩展可能返回随机的垃圾,如果它们不使用Unicode,就不能保证它们执行有效的x到Unicode转换)。目标编码可能是ASCII,尽管它在技术上必须匹配系统的当前代码页。
如果你想要一个有损的unicode到ascii的转换,你可以使用WideCharToMultiByte()
如果你不喜欢widechar,想要ansi字符串,试试wcstombs或WideCharToMultiByte。
调用SHGetKnownFolderPath不需要自己分配内存,否则会导致内存泄漏
- wcstombs_s(),转换字符串的长度
- 使用 CStringW/CStringA 和 CT2W/CT2A 转换字符串有什么区别?
- 无法转换字符串插入函数的参数
- 转换字符串向量:基于先前的值跳过元素
- 从中间器转换字符串不起作用,出了什么问题?
- 失败的证明转换字符串到枚举类
- 如何使用正则表达式和提升转换迭代器标记和转换 c 字符串
- 使用java jni时转换字符串类型
- 如何避免在转换字符串令牌流时重复istringstream构造
- 阿托伊未正确转换字符串
- C++,转换字符串,使连续下划线序列变为单个下划线
- 使用长算术转换字符串
- 转换字符串十进制数时的精度
- 将词法转换字符串提升为双精度
- 使用marshal_as函数转换字符串的性能
- C++不会从数据转换字符串
- 无论如何,在c++ /Qt中转换字符串到结构中的字段
- C++ 隐式类型转换字符串 -> int?
- 转换字符串到浮点数,c++实现
- 用于转换字符串大小写的函数