如何在C++中将PWSTR转换为字符串?

Tow*_*wer 5 c++ windows

我有以下代码:

// 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";
Run Code Online (Sandbox Code Playgroud)

stringstreamer的结果.str()008F6788/Google/Chrome/Application/chrome.exe,这是错误的.

我似乎无法使用stringstreamer工作,由于类型不兼容,strcat或wcsncat也没有.

如何将此PWSTR强制转换为字符串?

Lig*_*ica 29

Yuk!

微软:

typedef wchar_t* LPWSTR, *PWSTR;
Run Code Online (Sandbox Code Playgroud)

所以,让我们从你的测试用例中得到那个可怕的废话,并丢失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;
Run Code Online (Sandbox Code Playgroud)

2.警告!

这里有一个严重的缺陷.

SHGetKnownFolderPath实际上设置指针的值,指向分配的内存.你的代码有内存泄漏,我的最后一个代码段错误地释放了内存.

让我们通过阅读文档来解决这个问题:

ppszPath [out]

Type: PWSTR*
Run Code Online (Sandbox Code Playgroud)

此方法返回时,包含指向以null结尾的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));
Run Code Online (Sandbox Code Playgroud)

现在,随着节目.


3.广角

您的代码的语法问题是localAppData是一个wchar_t,但正常stringstream的工作char.

幸运的是,有一个广泛的char变体叫做wstringstream使用wchar_t.

(请注意,这意味着您的文字也必须wchar_t使用L字符串文字前缀从s 构建.)

现在最后的代码:

// 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));
Run Code Online (Sandbox Code Playgroud)

  • @AJG85:我的回答中没有向量。`SHGetKnownFolderPath` 为你做分配。 (2认同)
  • @Tomalak 你的代码也有问题 :-) `CoTaskMemFree` 需要一个空指针,而不是一个指向空指针的指针。 (2认同)
  • 谁知道听起来像查询操作系统路径这样简单的事情会变成这样一个雷区! (2认同)

Pra*_*ian 5

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";
Run Code Online (Sandbox Code Playgroud)

另外,malloc参数指示要分配的字节数,因此您分配的缓冲区只能容纳 64 个宽字符(包括 NULL 字符)。您可能想使用malloc( 128 * sizeof(wchar_t) ).

编辑:
来自文档SHGetKnownFolderPath

ppszPath当此方法返回时,包含指向以 null 结尾的 Unicode 字符串的指针的地址,该字符串指定已知文件夹的路径。一旦不再需要该资源,调用进程负责通过调用释放该资源CoTaskMemFree

因此,您不应该为函数的最后一个参数分配任何内存。

wchar_t *localAppData = NULL;
::SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);

wstringstream ss;
ss << localAppData << L"/Google/Chrome/Application/chrome.exe";
::CoTaskMemFree(localAppData);
Run Code Online (Sandbox Code Playgroud)