Reputation: 11
is there better way for making path through Environment variables in c/c++ than this?
char *S1 = std::getenv("SystemDrive");
char *S2 = std::getenv("USERNAME");
strcat(S1,"\\\\Users\\\\");
strcat(S1,S2);
strcat(S1,"\\\\");
strcat(S1,"Documents");
Upvotes: 0
Views: 524
Reputation: 2624
I would recommend getting the user profile directory something like this.
BOOL GetCurrentUserDir(LPTSTR lpszBuf, LPDWORD lpdwBuflen)
{
HANDLE hProcessToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hProcessToken))
return FALSE;
if (!GetUserProfileDirectory(hProcessToken, lpszBuf, lpdwBuflen)) {
CloseHandle(hProcessToken);
return FALSE;
}
CloseHandle(hProcessToken);
return TRUE;
}
I used this function like so:
WCHAR szLocalPath[MAX_PATH];
if (!GetCurrentUserDir(szLocalPath, &cchPath))
{
//Handle the error
}
You can then append the rest of the path.
This encapsulates the specific environment variables and makes use of the Win32 API. This is more likely to remain portable over time.
Upvotes: 2
Reputation: 4511
Not sure to understand what you need exactly. Is this to create paths from environment variables ? or to get proper paths of system directory ? in the latter case, you would better use the Win32 API, e.g.: SHGetFolderPath
or SHGetKnownFolderPath
.
#include <Windows.h>
#include <ShellAPI.h>
#include <KnownFolders.h>
#include <ShlObj.h>
int main()
{
CoInitialize(NULL);
TCHAR* path = 0;
SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_SIMPLE_IDLIST, NULL, &path);
// use collected 'path' here
CoTaskMemFree(path); // free the TCHAR object allocated by SHGetKnownFolderPath
return 0;
}
The above code retrieve the current user "My Documents" folder path.
Upvotes: 0
Reputation: 3802
std::getenv
is deprecated.
I would use something in the likes:
char* wSystemDrive = nullptr;
size_t wSize = 0;
bool wFree = true;
if(_dupenv_s(&wSystemDrive,&wSize,"SystemDrive") != 0 || wSystemDrive == nullptr)
{
wFree = false;
wSystemDrive = "C:\\"; //or anything default you want to use
}
std::string wSysteDriveString(wSystemDrive);
if(wFree)
{
free(wSystemDrive);
}
char* wUSERNAME = nullptr;
wSize = 0;
wFree = true;
if(_dupenv_s(&wEnv,&wSize,"wUSERNAME") != 0 || wUSERNAME == nullptr)
{
wFree = false;
wUSERNAME = "User";
}
std::string wUSERNAMEString(wUSERNAME);
if(wFree)
{
free(wUSERNAME);
}
std::string wPath = wSystemDriveString + "\\Users\\" + wUSERNAMEString + "\\Documents"
Note that you do not need 4 \
(\\\\
), only two (\\
).
Upvotes: -1
Reputation: 136296
One good way to concatenate multiple strings is to use snprintf
:
char buf[0x10000];
int n = std::snprintf(buf, sizeof buf, "%s\\\\Users\\\\%s\\\\Documents", S1, S2);
if(static_cast<size_t>(n) >= sizeof buf)
// Buffer is too small (if n > 0) or error
The fact that snprintf
does not overflow the buffer and always zero-terminates makes unsafe functions strcpy
, strncpy
, strcat
unnecessary.
Upvotes: 1
Reputation: 251
Why don't you use std::string?
std::string s1 = std::getenv("SystemDrive");
s1 += "\\\\Users\\\\" + std::getenv("USERNAME") + "\\\\Documents";
Upvotes: 1