使用WinAPI获取C中当前用户的桌面路径
我对WinAPI编程非常陌生。我想知道如何获得用户桌面的路径,然后打印出控制台的完整路径。这是我当前的代码:使用WinAPI获取C中当前用户的桌面路径,c,winapi,C,Winapi,我对WinAPI编程非常陌生。我想知道如何获得用户桌面的路径,然后打印出控制台的完整路径。这是我当前的代码: TCHAR* path = 0; HRESULT result = SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path); if (result == S_OK) { printf("%s\n", path); } CoTaskMemFree(path) 它确实找到了路径,但它打印出路径的“C”,而不是带
TCHAR* path = 0;
HRESULT result = SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
if (result == S_OK)
{
printf("%s\n", path);
}
CoTaskMemFree(path)
它确实找到了路径,但它打印出路径的“C”,而不是带斜杠的整个路径。我错过了什么
谢谢 它只打印一个字符,因为您试图将宽字符串打印为窄字符串。您可能已经定义了UNICODE/\uUnicode,因此TCHAR就是WCHAR 如果您坚持使用TCHAR,则应使用TCHAR中的正确打印功能。h:
_tprintf(_T("%s\n"), path);
否则,您可以使用宽版本:
wprintf(L"%s\n", path);
或者,最糟糕的解决方案是将字符串转换为窄码页字符串:
printf("%ls\n", path); // This might not display all Unicode characters correctly
它只打印一个字符,因为您试图将宽字符串打印为窄字符串。您可能已经定义了UNICODE/\uUnicode,因此TCHAR就是WCHAR 如果您坚持使用TCHAR,则应使用TCHAR中的正确打印功能。h:
_tprintf(_T("%s\n"), path);
否则,您可以使用宽版本:
wprintf(L"%s\n", path);
或者,最糟糕的解决方案是将字符串转换为窄码页字符串:
printf("%ls\n", path); // This might not display all Unicode characters correctly
SHGetKnownFolderPath()
输出一个wchar\u t*
指针,而不是TCHAR*
指针。没有ANSI版本的SHGetKnownFolderPath()
,因此在这种情况下不应该使用TCHAR
。事实上,除非定义了UNICODE
,这样TCHAR
映射到wchar\t
,否则代码不会编译
之所以只看到第一个字符,是因为您正在传递一个wchar\u t*
,其中需要一个char*
。在Windows上,wchar\u t
为16位,因此wchar\u t*
字符串以UCS-2或UTF-16LE编码。UCS-2/UTF-16LE中的所有ASCII字符的高8位都设置为0。您使用的printf()
需要一个以null结尾的char*
字符串,因此第一个wchar\t
字符的高0x00字节被误解为null终止符
要执行所需操作,需要将返回的路径打印为宽字符串,而不是(被误解的)窄字符串
您可以将%S
与printf()一起使用,例如:
PWSTR path;
if (SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path) == S_OK)
{
printf("%S\n", path);
CoTaskMemFree(path);
}
但这在编译器之间是不可移植的。您应该将%s
与wprintf()
一起使用:
PWSTR path;
if (SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path) == S_OK)
{
wprintf(L"%s\n", path);
CoTaskMemFree(path);
}
SHGetKnownFolderPath()
输出一个wchar\u t*
指针,而不是TCHAR*
指针。没有ANSI版本的SHGetKnownFolderPath()
,因此在这种情况下不应该使用TCHAR
。事实上,除非定义了UNICODE
,这样TCHAR
映射到wchar\t
,否则代码不会编译
之所以只看到第一个字符,是因为您正在传递一个wchar\u t*
,其中需要一个char*
。在Windows上,wchar\u t
为16位,因此wchar\u t*
字符串以UCS-2或UTF-16LE编码。UCS-2/UTF-16LE中的所有ASCII字符的高8位都设置为0。您使用的printf()
需要一个以null结尾的char*
字符串,因此第一个wchar\t
字符的高0x00字节被误解为null终止符
要执行所需操作,需要将返回的路径打印为宽字符串,而不是(被误解的)窄字符串
您可以将%S
与printf()一起使用,例如:
PWSTR path;
if (SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path) == S_OK)
{
printf("%S\n", path);
CoTaskMemFree(path);
}
但这在编译器之间是不可移植的。您应该将%s
与wprintf()
一起使用:
PWSTR path;
if (SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path) == S_OK)
{
wprintf(L"%s\n", path);
CoTaskMemFree(path);
}
通常,您可以在函数名的末尾添加“A”来选择ASCII版本,但根据MSDN,这是一个win32函数,只有unicode版本--“Out PWSTR*ppszPath”,因此它不是SHGetKnownFolderPathW的别名,它不存在。@DaveS啊,是的,很好,我想到的是旧的特殊文件夹函数。使用“A”版本不是一个好主意,它不能处理所有Unicode路径代码>也是一个选项?@zzxyz%S与此选项中的%ls相同case@Anders:这就是我的观点:TCHAR的全部要点是映射到char或wchar\t。在这种情况下,您不能这样做,因此它根本不应该使用TCHAR。它应该使用wchar_t(或wchar),因为它必须始终使用宽字符。通常,您可以在函数名的末尾添加“A”来选择ASCII版本,但根据MSDN,这是一个win32函数,只有unicode版本--“Out PWSTR*ppszPath”,因此它不是SHGetKnownFolderPathW的别名,这是不存在的。@DaveS啊,是的,很好,我想到的是旧的特殊文件夹函数。使用“A”版本不是一个好主意,它不能处理所有Unicode路径代码>也是一个选项?@zzxyz%S与此选项中的%ls相同case@Anders:这就是我的观点:TCHAR的全部要点是映射到char或wchar\t。在这种情况下,您不能这样做,因此它根本不应该使用TCHAR。它应该使用wchar\u t(或wchar),因为它必须始终使用宽字符。TCHAR对您没有好处,因为您不支持Windows 98。因此,请使用wchar\u t并只使用本机Unicode API。TCHAR对您没有好处,因为您不支持Windows 98。因此,请使用wchar__t,并只使用本机Unicode API。