Getting the working directory and converting to a string

As the title says, I am trying to get the working directory and convert it from a LPWSTR to a string. It has to be ASCII and not Unicode because functions later in the code do not support Unicode. Can anyone help me figure out why this isn't working and how to do it right.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
	char * laWorkingDirectory;
	LPWSTR lwWorkingDirectory;

//get directory of type LPWSTR
	GetCurrentDirectory(GetCurrentDirectory(0, NULL),
		lwWorkingDirectory);
//convert to char *
	WideCharToMultiByte(CP_ACP,
		NULL,
		lwWorkingDirectory,
		-1,
		laWorkingDirectory,
		WideCharToMultiByte(CP_ACP, NULL, lwWorkingDirectory, -1, NULL, 0, NULL, NULL),
		NULL,
		NULL);
//convert to string
	string lWorkingDirectory = string(laWorkingDirectory);
	string lFileName = "";
//delete temp directories
	delete [] lwWorkingDirectory, laWorkingDirectory;
Last edited on
Either
1
2
3
4
5
6
7
8
9
10
#include <direct.h>
#include <string>

std::string current_working_directory()
{
    char* cwd = _getcwd( 0, 0 ) ; // **** microsoft specific ****
    std::string working_directory(cwd) ;
    std::free(cwd) ;
    return working_directory ;
}


or
1
2
3
4
5
6
7
8
9
#include <windows.h>
#include <string>

std::string current_working_directory()
{
    char working_directory[MAX_PATH+1] ;
    GetCurrentDirectoryA( sizeof(working_directory), working_directory ) ; // **** win32 specific ****
    return working_directory ;
}


Your use of GetCurrentDirectory() is incorrect. The function returns the required buffer, but you never allocate that buffer. This is bound to fail. First find out the required buffer size, then allocate the buffer, then get the data.

But most importantly, you CAN get the directory as an ANSI string directly!

1
2
3
DWORD buffSize = GetCurrentDirectoryA(0, NULL);
laWorkingDirectory = new char[buffSize];
GetCurrentDirectoryA(buffSize, laWorkingDirectory);


And that's it. You have your data in ANSI format. Note that it is ANSI and not ASCII. ASCII is a 7-bit codepage, while ANSI is an 8-bit codepage.
> Your use of GetCurrentDirectory() is incorrect. The function returns the required buffer,
> but you never allocate that buffer. This is bound to fail.
> First find out the required buffer size, then allocate the buffer, then get the data.

Either RTFM
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364934(v=vs.85).aspx
If the buffer that is pointed to by lpBuffer is not large enough, the return value specifies the required size of the buffer, in characters, including the null-terminating character.



Or test the actual code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <Windows.h>
#include <string>

std::string current_working_directory()
{
    char working_directory[MAX_PATH+1] ;
    GetCurrentDirectoryA( sizeof(working_directory), working_directory ) ; // **** win32 specific ****
    return working_directory ;
}

int main()
{
    std::cout << current_working_directory() << '\n' ;
}


or both. Before making vacuous pronouncements.
Last edited on
LOL JLBorges, I am talking about the code in the orginal post. I replied and had no idea you had replied before me. Now get a hold of yourself. And remember this: Concurrency: A poster may post while you are typing YOUR post, so even though it seems that I *should* have known you had posted, well, I didn't.

So YOU think through before you write stupid comments. Nice word, though. Vacuous.
Ok. Fair enough.
Wow, I left expecting it to take a while for a reply. Anyway, both codes work. I decided to go with WebJose's code just because it gets the size needed for the buffer. I'm trying to keep memory to a minimum. I just noticed that msdn gives ANSI and Unicode equivilants at the very bottom in small print.

One last thing that is really stupid, I don't think the working directory is what I needed. It is giving me the directory of the project. I need the directory of where it is running, which is where it was built.
I don't know a direct route, so I'd do this:

1. Use GetModuleFileName() to obtain the full path and exe file name. http://msdn.microsoft.com/en-us/library/windows/desktop/ms683197(v=vs.85).aspx
2. Strip the file name using PathRemoveFileSpec(). http://msdn.microsoft.com/en-us/library/windows/desktop/bb773748(v=vs.85).aspx
Sorry for the late reply. I still can't get it to work.
1
2
3
	char *lWorkingDirectory = new char[MAX_PATH];
	GetModuleFileNameA(NULL, lWorkingDirectory, MAX_PATH);
	PathRemoveFileSpecA(lWorkingDirectory);


I'm getting this error at compile time.
TestCM.obj : error LNK2019: unresolved external symbol __imp__PathRemoveFileSpecA@4 referenced in function _main
\Projects\TestCM\Debug\TestCM.exe : fatal error LNK1120: 1 unresolved externals

I thought it might be a linking error, but i added #include <Shlwapi.h> for the PathRemoveFileSpecA(), and it's library is standard.

Do you have any idea what it is wrong?
Link errors are not solved with #includes; they are solved with lib's. Add the following line to a single CPP file:

#pragma comment(lib, "Shlwapi.lib")

The lib filename is always listed in the MSDN Online documentation, at the bottom of the page.
¿Isn't there an environment variable that holds the working directory?
I believe it's _get_pgmptr if that is what you're referring to. Thanks for that webJose. I thought I just needed to add the library to the project properties, but this fixed all the problems. This forum rocks! :)
Topic archived. No new replies allowed.