Как получить текущий каталог в программе на C?


163

Я делаю программу на C, где мне нужно получить каталог, из которого запускается программа. Эта программа написана для компьютеров UNIX. Я смотрел opendir()и telldir(), но telldir()возвращает off_t (long int), так что это действительно не помогает мне.

Как я могу получить текущий путь в строке (массив символов)?

Ответы:


292

Вы смотрели getcwd()?

#include <unistd.h>
char *getcwd(char *buf, size_t size);

Простой пример:

#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;
}

11
Выбирая самый тонкий из nits, <errno.h> кажется ненужным, и программа сообщает об успехе даже при неудаче через состояние выхода. В противном случае хороший пример.
Джонатан Леффлер

21
О, и более ли принято использовать printf (...) вместо fprintf (stdout, ...)?
Джонатан Леффлер

19
@JonathanLeffler: Это не самая придирчивая из гнид. Это: int main()должно быть int main(void).
Кит Томпсон,

4
Я бы использовал PATH_MAX из limit.h вместо магического числа, если ~ 4KB в стеке не является проблемой.
jacekmigacz

1
Тем не менее, ваш буфер должен также вместить байт / ноль в конце строки, поэтому правильный - char cwd[PATH_MAX+1]. Или, если вы не можете быть обеспокоены буферами только char *buf=getcwd(NULL,0);и когда вы закончите free(buf)(по состоянию на POSIX.1-2001)
bliako

60

Посмотрите справочную страницу для getcwd.


7
@angad научить человека ловить рыбу, но, по крайней мере, покажите ему путь к озеру / морю / океану :)
MTK

3
люди, которые рекомендуют людей людям, пытающимся использовать значительно более совершенный метод поиска Google, не работают.
gbtimmon

3
Фрагмент кода: man 3 getcwd. Помимо шуток, не будьте анархонистами, этот пост написан в '08, так что соглашения были другими.
Кролтан

2
@gbtimmon google - это поисковая система, она не похожа на страницу руководства. Это в конечном итоге будет указывать на справочную страницу.
Аджай Брахмакшатрия

24

Хотя вопрос помечен Unix, люди также посещают его, когда их целевой платформой является Windows, а ответом для Windows является GetCurrentDirectory()функция:

DWORD WINAPI GetCurrentDirectory(
  _In_  DWORD  nBufferLength,
  _Out_ LPTSTR lpBuffer
);

Эти ответы относятся как к C, так и к C ++ коду.

Ссылка, предложенная пользователем 4581301 в комментарии к другому вопросу и подтвержденная в качестве текущей наиболее популярной, с помощью поиска Google 'site: microsoft.com getcurrentdirectory'.


2
#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;
}

3
Почему бы вам не использовать предопределенные макросы для определения ОС, например, #iffined (_WIN32) || определено (_WIN64) || определено ( WINDOWS )
HaseeB Мир

1

Обратите внимание, что getcwd(3)он также доступен в libc: getcwd (3) от Microsoft и работает так же, как вы ожидаете.

Необходимо связать с -loldnames(oldnames.lib, что в большинстве случаев делается автоматически) или использовать _getcwd(). Версия без префикса недоступна в Windows RT.


0

Чтобы получить текущий каталог (в котором вы выполняете целевую программу), вы можете использовать следующий пример кода, который работает как для Visual Studio, так и для Linux / MacOS (gcc / clang), как для C, так и для C ++:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_MSC_VER)
#include <direct.h>
#define getcwd _getcwd
#elif defined(__GNUC__)
#include <unistd.h>
#endif

int main() {
    char* buffer;

    if( (buffer=getcwd(NULL, 0)) == NULL) {
        perror("failed to get current directory\n");
    } else {
        printf("%s \nLength: %zu\n", buffer, strlen(buffer));
        free(buffer);
    }

    return 0;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.