0

#include <iostream>
#include <string> 
#include <fstream>
//---
using namespace std;
//---
int main()
{

    string myFile = "theName.txt"; 
    std::string combined = "echo %USERPROFILE% >> C:\\Windows\\Temp\\"+ myFile ;
    system(combined.c_str());

    fstream dog;
    std::string combined2 = "C:\\Windows\\Temp\\" + myFile; 
    dog.open(combined2.c_str());
    char data[100];
    dog >> data; 
    cout << data;

    int cat = 0;
    cin >> cat;
    return 0;
}
//--
//---
//------------------------------------------------------------------------------------

Could be better... although in terms of simplicity so far the best way of looking at it... I have gone over a few answer to the problem online and what I've learned is pretty simple... Coding without the namespace std; I obviously just learned that.

Looking at what edits I should get on... I see... That not only should I remove the file, but that I also should retrive the explicit user name from the string...

Fabio A.
  • 2,517
  • 26
  • 35
Dana M
  • 1
  • 4
  • 3
    `std::getenv("USERPROFILE");`? Not sure whether it works on Windows just like that. – Quimby Jul 24 '23 at 06:45
  • 1
    @Quimby [Does](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getenv-wgetenv?view=msvc-170) ;) – Aconcagua Jul 24 '23 at 06:46
  • 1
    [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Jesper Juhl Jul 24 '23 at 06:47
  • There's also [GetUserName](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getusernamea) function (and a ...Ex variant of). – Aconcagua Jul 24 '23 at 06:48
  • You're going about it the very convoluted way. Instead, have a look at [std::getenv()](https://en.cppreference.com/w/cpp/utility/program/getenv) if you want to access the environmental variable, or at the [GetUserName()](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getusernamea) Win32 call if you want to have a more direct access to it. – Fabio A. Jul 24 '23 at 06:48
  • No doubt using using namespace std; leads to some serious problems in practice. NO doubt you probably outta use the std::getenv() or GetUserName but in this scenario one has no clue how to https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getusernamea from just right there. – Dana M Jul 24 '23 at 06:53
  • @DanaM You need a bit of experience what's behind those MS macros (`LPSTR` simply is a `char*`, `LPDWORD` is a `unsigned long*`). WinAPI is full of such bad pracice (providing defines for pointers, etc), unfortunately. Once you know then the documentation should provide all the information you need, though. Mainly the API requires a buffer of sufficient size: `char userName[UNLEN + 1]; unsigned long length = sizeof(userName); if(GetUserNameA(userName, &length) != 0) { /* 'userName' array contains the user name string, 'length' the latter's length */ }`. – Aconcagua Jul 24 '23 at 07:08
  • General advice: Whenever you deal WinAPI you can lookup that information yourself, any decent IDE should be able to lead you to definitions/declarations, e.g. eclipse via ctrl + left-click (by default, is customisable), most others have an entry for in right-click context menu. Do that first for the function and from there on for the parameter types (repeatedly, until you discover the base definition, usually to a standard language type). – Aconcagua Jul 24 '23 at 07:19
  • @DanaM did you follow the "example" link? Learning to understand the documentation will ultimately be more productive than posting questions in Stack Overflow. That said, ideally an answer should be posted rather than given in a comment. – Clifford Jul 24 '23 at 07:35
  • 2
    Rule of thumb: `system()` to retrieve information -> wrong. – DevSolar Jul 24 '23 at 07:36

2 Answers2

2

That is a very indirect and cumbersome way if doing it. You never need to resort to invoking shell commands to get operating system information of any kind.

In this case the Windows API call GetEnvironmentVariable() can retrieve environment variables directly:

static const DWORD MAXUNAMELEN = 128 ;
TCHAR username[128] ;

int unamelen = GetEnvironmentVariable( TEXT("USERPROFILE"), username, MAXUNAMELEN ) ;

Or using std::getenv() :

const char* username = std::getenv( "USERPROFILE" ) ;

That will get an environment variable, but even that is unnecessary (and potentially unsafe) if you specifically want the current user name, which is probably best retrieved with GetUserName():

TCHAR username[UNLEN + 1] ;
DWORD unamelen = sizeof(username) / sizeof(*username) ;

bool success = GetUserName( username, &unamelen ) ;

Note that the macros such as TCHAR and TEXT are defined for char or wchar_t depending on whether the build is Unicode or not. There are simpler char-only variants of text handling API's with an A suffix such as GetUserNameA(), GetEnvironmentVariable() that you might use instead.

Most of the Windows API documentation is supported by examples (usually for multiple related APIs). In this case, the following apply:

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • No need to define your own constant, there's already `UNLEN` from `Lmcons.h`, though array should be one larger in size (null-terminator), see `GetUserName` documentation. – Aconcagua Jul 24 '23 at 07:23
  • @Aconcagua Thanks. It was adapted from the environment variable solution, but that is better. – Clifford Jul 24 '23 at 07:31
  • `ULONG cb = _countof(username); GetUserName( username, &cb) ;` must be. – RbMm Jul 24 '23 at 07:46
  • @RbMm : That is what I get for trying to edit/post code using a phone! Fix in progress. – Clifford Jul 24 '23 at 09:23
  • @RbMm : there was no need to explain all that (to me at least), but the effort and attention to detail is appreciated. It was not just entering the code that was the issue, it was flipping between SO and the API reference (and having breakfast). Now I am on a PC with two screens. – Clifford Jul 24 '23 at 09:44
0
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <winbase.h>
#include <lmcons.h>
#include <string>




int wmain()
{
  
    TCHAR username[UNLEN + 1];
    DWORD unamelen = sizeof(username) / sizeof(*username);

    bool success = GetUserName(username, &unamelen);


    std::wcout << username; 
    return true;
}

AWESOME THANKS!

Ok after getting over the namespace of std a little bit more... which is what I intended to do... I have come up with the code using #Cliffords code in a .cpp...

A really basic one but this works and thanks! No has called me dumb... don't!

Dana M
  • 1
  • 4