Jak uzyskać bieżący katalog w programie C?

162

Robię program w C, w którym muszę pobrać katalog, z którego program jest uruchamiany. Ten program jest napisany dla komputerów z systemem UNIX. Patrzyłem na opendir()i telldir(), ale telldir()zwraca a off_t (long int), więc to naprawdę mi nie pomaga.

Jak mogę uzyskać bieżącą ścieżkę w ciągu (tablica znaków)?

Charles B.
źródło

Odpowiedzi:

291

Czy spojrzałeś na getcwd()?

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

Prosty przykład:

#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;
}
Mic
źródło
11
Wybranie najbardziej wybrednego z nitów, <errno.h> wydaje się niepotrzebne, a program zgłasza sukces nawet w przypadku niepowodzenia poprzez swój status wyjścia. W przeciwnym razie ładny przykład.
Jonathan Leffler
21
Aha, i czy bardziej konwencjonalne jest użycie printf (...) zamiast fprintf (stdout, ...)?
Jonathan Leffler
19
@JonathanLeffler: To nie jest najbardziej wybredna z gnid. To jest: int main()powinno być int main(void).
Keith Thompson
4
Użyłbym PATH_MAX z limits.h, zamiast magicznej liczby, jeśli ~ 4KB na stosie nie stanowi problemu.
jacekmigacz
1
Nadal nie ma, twój bufor powinien również pomieścić bajt / null kończący łańcuch, dlatego poprawny jest char cwd[PATH_MAX+1]. Lub jeśli nie możesz się przejmować buforami tylko char *buf=getcwd(NULL,0);i kiedy skończysz free(buf)(stan
POSIX.1-2001
60

Wyszukaj stronę podręcznika dla getcwd.

CAdaker
źródło
7
@angad naucz człowieka łowić ryby, ale przynajmniej pokaż mu drogę do jeziora / morza / oceanu :)
mtk
3
ludzie polecający człowieka ludziom próbującym użyć znacznie lepszej metody wyszukiwania google są poza kontaktem.
gbtimmon
3
Fragment kodu: man 3 getcwd. Żarty na bok, nie bądź anarchonistyczny, ten post pochodzi z 2008 roku, konwencje SO były inne.
Kroltan
2
@gbtimmon google to wyszukiwarka, nie jest analogiczna do strony man. W końcu wskaże stronę podręcznika.
Ajay Brahmakshatriya
24

Chociaż pytanie jest oznaczone jako Unix, ludzie mogą je również odwiedzać, gdy ich platformą docelową jest Windows, a odpowiedzią dla systemu Windows jest GetCurrentDirectory()funkcja:

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

Te odpowiedzi dotyczą zarówno kodu C, jak i C ++.

Link zasugerowany przez użytkownika4581301 w komentarzu do innego pytania i zweryfikowany jako aktualnie najlepszy wybór w wyszukiwarce Google „site: microsoft.com getcurrentdirectory”.

Jonathan Leffler
źródło
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;
}
Jevgenij Kononov
źródło
3
Dlaczego nie używasz wstępnie zdefiniowanych makr do wykrywania systemu operacyjnego, takiego jak #if zdefiniowane (_WIN32) || zdefiniowane (_WIN64) || zdefiniowane ( WINDOWS )
HaseeB Mir
1

Zauważ, że getcwd(3)jest również dostępny w libc: getcwd (3) Microsoftu i działa w taki sam sposób, jakiego można się spodziewać.

Musi łączyć się z -loldnames(oldnames.lib, co w większości przypadków odbywa się automatycznie) lub używać _getcwd(). Wersja bez prefiksu jest niedostępna w systemie Windows RT.

rvx
źródło
0

Aby uzyskać bieżący katalog (w którym wykonujesz program docelowy), możesz użyć następującego przykładowego kodu, który działa zarówno dla Visual Studio, jak i Linux / MacOS (gcc / clang), zarówno C, jak i 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;
}
HaxtraZ
źródło