How to get the current directory in a C program?
Solution 1
Have you had a look at getcwd()
?
#include <unistd.h>
char *getcwd(char *buf, size_t size);
Simple example:
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
int main() {
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
printf("Current working dir: %s\n", cwd);
} else {
perror("getcwd() error");
return 1;
}
return 0;
}
Solution 2
Look up the man page for getcwd
.
Solution 3
Although the question is tagged Unix, people also get to visit it when their target platform is Windows, and the answer for Windows is the GetCurrentDirectory()
function:
DWORD WINAPI GetCurrentDirectory(
_In_ DWORD nBufferLength,
_Out_ LPTSTR lpBuffer
);
These answers apply to both C and C++ code.
Link suggested by user4581301 in a comment to another question, and verified as the current top choice with a Google search 'site:microsoft.com getcurrentdirectory'.
Solution 4
#include <stdio.h> /* defines FILENAME_MAX */
//#define WINDOWS /* uncomment this line to use it for windows.*/
#ifdef WINDOWS
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif
int main(){
char buff[FILENAME_MAX];
GetCurrentDir( buff, FILENAME_MAX );
printf("Current working dir: %s\n", buff);
return 1;
}
Solution 5
Note that getcwd(3)
is also available in Microsoft's libc: getcwd(3), and works the same way you'd expect.
Must link with -loldnames
(oldnames.lib, which is done automatically in most cases), or use _getcwd()
. The unprefixed version is unavailable under Windows RT.
Related videos on Youtube
CharlesB
Updated on January 13, 2022Comments
-
CharlesB over 2 years
I'm making a C program where I need to get the directory that the program is started from. This program is written for UNIX computers. I've been looking at
opendir()
andtelldir()
, buttelldir()
returns aoff_t (long int)
, so it really doesn't help me.How can I get the current path in a string (char array)?
-
Jonathan Leffler over 15 yearsPicking the pickiest of nits, <errno.h> seems unnecessary, and the program reports success even on failure via its exit status. Otherwise, a nice example.
-
Jonathan Leffler over 15 yearsOh, and is it more conventional to use printf(...) in place of fprintf(stdout, ...)?
-
Keith Thompson about 9 years@JonathanLeffler: That's not the pickiest of nits. This is:
int main()
should beint main(void)
. -
mtk over 8 years@angad teach a man to fish but atleast show him path to the lake/sea/ocean :)
-
gbtimmon over 8 yearspeople recommending man to people trying to use the vastly superior search method google are out of touch.
-
Kroltan about 8 yearsCode snippet:
man 3 getcwd
. Jokes aside, don't be anarchonistic, this post is from '08, SO conventions were different. -
jacekmigacz over 7 yearsI would use PATH_MAX from limits.h, instead of magic number if ~4KB on stack is not an issue.
-
Ajay Brahmakshatriya almost 7 years@gbtimmon google is a search engine, it is not analogous to man page. It is eventually going to point to the man page.
-
Haseeb Mir over 5 yearsWhy don't you use pre_defined macros for detecting OS like #if defined(_WIN32) || defined(_WIN64) || defined(WINDOWS)
-
bliako over 5 yearsStill not there, your buffer should also accommodate for the string-termination byte/null, therefore the correct one is
char cwd[PATH_MAX+1]
. Or if you can't be bothered with buffers justchar *buf=getcwd(NULL,0);
and when you are donefree(buf)
(as of POSIX.1-2001) -
Accountant م over 5 yearsIf I run the program from a
cron
this function will not return the directory of the program as expected. -
Andrew Henle over 4 years@bliako But still not there.
PATH_MAX
is not necessarily defined: "A definition of one of the symbolic constants in the following list shall be omitted from the<limits.h>
header on specific implementations where the corresponding value is equal to or greater than the stated minimum, but where the value can vary depending on the file to which it is applied. The actual value supported for a specific pathname shall be provided by thepathconf()
function." -
bliako over 4 years@Andrew Henle, that's why I offered the PATH_MAX-less solution.
-
DanielSchreiberMendes about 4 yearsShouldn't it be
sizeof cwd
instead ofsizeof(cwd)
? -
Liam over 3 yearsIn Linux (glibc),
get_current_dir_name()
is a bit more convenient (does its own malloc). I wanted to get just the directory name, not the entire path, so I didbasename(get_current_dir_name())
. -
Omarito over 2 yearsYour second example leaks memory. I'm aware that the OS will clear all memory allocate for the process anyway in this case but think about the people that come will copy the code without paying attention this will potentially cause deep problems for them later.
-
Gulzar over 2 years@AjayBrahmakshatriya The correct Google term is "How to get cwd in C++". If that gets a man page, the term changes to "How to get cwd in C++ Stack Overflow".
-
Andrew Henle over 2 years@Liam If
get_current_dir_name()
does its ownmalloc()
,basename(get_current_dir_name())
is an unfixable memory leak. -
floydheld over 2 yearsIt doesn't seem to me that this is c... is it? LPTSTR?
-
Jonathan Leffler over 2 years@floydheld — It is C but it is using Microsoft Windows type names. Many of those are all upper-case letters (and numbers and underscores), in contrast to most other systems where the types are all lower-case instead (with some exceptions:
FILE
andDIR
spring to mind in POSIX systems). -
Jonathan Leffler over 2 yearsIf the code in HaseeB Mir's comment was enclosed in back-quotes, I believe it would look like:
#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
. The bold WINDOWS strongly hints at double-underscores before and after 'WINDOWS'. However, looking at some corporate code that caters to Windows (as well as Unix) builds, I find#if defined(_WINDOWS) || defined(_WIN32) || defined(_WIN64)
— YMMV.