我很确定这已在某个地方得到解答,但我找不到答案(我可能是盲人)。但是,我有这段代码:
TCHAR name[UNLEN + 1];
DWORD size = UNLEN + 1;
char path[250]; = "X:\\users\\HEREname\\Documents\\Games\\";
注意:TCHAR
只是char
的typedef而DWORD
是unsigned
int的typedef。
所以我很想知道格式化name
中path
的正确方法是什么,以便“HEREname”被name
字符替换。我无法真正找到如何使用字符串和dunno为什么我找不到它....:/
谢谢!
答案 0 :(得分:1)
TCHAR
可能是char
的typedef,或者可能是wchar_t
的typedef。这取决于您的项目是否配置为MBCS(char
)或Unicode(wchar_t
)。由于path[]
明确char
,name
应该使用char
来匹配,而不是TCHAR
。否则,如果TCHAR
为wchar_t
,则必须执行运行时转换。
对于您尝试的内容,您可以使用snprint()
(或TCHAR
等效,_sntprintf()
)或类似功能,例如:
char name[UNLEN + 1];
DWORD size = UNLEN + 1;
if (GetUserNameA(name, &size))
{
char path[MAX_PATH] = {0};
int len = snprintf(path, MAX_PATH, "X:\\users\\%s\\Documents\\Games\\", name);
if ((len > 0) && (len < MAX_PATH))
{
...
}
}
或者:
TCHAR name[UNLEN + 1];
DWORD size = UNLEN + 1;
if (GetUserName(name, &size))
{
TCHAR path[MAX_PATH] = {0};
int len = _sntprintf(path, MAX_PATH, _T("X:\\users\\%s\\Documents\\Games\\"), name);
if ((len > 0) && (len < MAX_PATH))
{
...
}
}
或者,如果你真的需要混合TCHAR
和char
(我不推荐):
#ifdef UNICODE
#define PRINTF_TSTR_FMT "%ls"
#else
#define PRINTF_TSTR_FMT "%s"
#endif
TCHAR name[UNLEN + 1];
DWORD size = UNLEN + 1;
if (GetUserName(name, &size))
{
char path[MAX_PATH] = {0};
int len = snprintf(path, MAX_PATH, "X:\\users\\" PRINTF_TSTR_FMT "\\Documents\\Games\\", name);
if ((len > 0) && (len < MAX_PATH))
{
...
}
}
话虽这么说,你真的不应该假设Windows存储用户配置文件的位置。不同机器上的位置可能不同,尤其是在不同版本的Windows上。使用Shell API来查询系统路径,例如:
TCHAR path[MAX_PATH] = {0};
if (SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path) == S_OK)
{
if (PathAppend(path, TEXT("Games")))
{
// use path as needed...
}
}
或者,在Vista及更高版本上:
PWSTR pDocsPath = NULL;
// or maybe even FOLDERID_Games...
if (SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &pPath) == S_OK)
{
TCHAR path[MAX_PATH] = {0};
bool bOK = (PathCombine(path, pDocsPath, TEXT("Games")) != NULL);
CoTaskMemFree(pDocsPath);
if (bOK)
{
// use path as needed...
}
}
答案 1 :(得分:0)
有两种方法:
//Paths in C++ can all use '/', they don't need to have system-specific delimiters
std::string root = "X:/users/"
std::string user_name = /*...*/;
std::string path = "/Documents/Games/";
std::string final_path = root + user_name + path;
//TODO: Input sanitizing, to ensure no chance of rogue code
std::fstream file(final_path + file_name, /*...*/);
这可能是最简单的方法。
这种方法更具性能:
std::stringstream path;
path << "X:/Users/";
path << user_name;
path << "/Documents/Games/";
path << file_name;
std::string final_path = path.str();
std::fstream file(final_path, /*...*/);
如果你有一个符合C ++ 17的编译器,那么这是非常受欢迎的:
std::filesystem::path path = "X:/users";
path /= user_name;
path /= "Documents";
path /= "Games";
std::fstream file(path / file_name, /*...*/);