Comment obtenir le répertoire courant dans un programme C?

163

Je crée un programme C où j'ai besoin d'obtenir le répertoire à partir duquel le programme est démarré. Ce programme est écrit pour les ordinateurs UNIX. J'ai regardé opendir()et telldir(), mais telldir()renvoie un off_t (long int), donc ça ne m'aide vraiment pas.

Comment puis-je obtenir le chemin actuel dans une chaîne (tableau de caractères)?

CharlesB
la source

Réponses:

292

Avez-vous jeté un coup d'œil getcwd()?

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

Exemple simple:

#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;
}
Micro
la source
11
Choisir le plus difficile des lentes, <errno.h> semble inutile, et le programme signale le succès même en cas d'échec via son statut de sortie. Sinon, un bel exemple.
Jonathan Leffler
21
Oh, et est-il plus conventionnel d'utiliser printf (...) à la place de fprintf (stdout, ...)?
Jonathan Leffler
19
@JonathanLeffler: Ce n'est pas la plus difficile des lentes. C'est: int main()devrait être int main(void).
Keith Thompson
4
J'utiliserais PATH_MAX de limits.h, au lieu du nombre magique si ~ 4 Ko sur la pile n'est pas un problème.
jacekmigacz
1
Toujours pas là, votre tampon devrait également accueillir l'octet de terminaison de chaîne / null, donc le bon est char cwd[PATH_MAX+1]. Ou si vous ne pouvez pas être dérangé par les tampons juste char *buf=getcwd(NULL,0);et quand vous avez terminé free(buf)(à partir de POSIX.1-2001)
bliako
60

Recherchez dans la page de manuel getcwd.

CAdaker
la source
7
@angad apprend à un homme à pêcher mais au moins lui montre le chemin vers le lac / la mer / l'océan :)
MTK
3
les gens qui recommandent l'homme aux personnes qui essaient d'utiliser la méthode de recherche largement supérieure google sont déconnectés.
gbtimmon
3
Extrait de code: man 3 getcwd. Blagues à part, ne soyez pas anarchoniste, cet article date de '08, les conventions SO étaient différentes.
Kroltan
2
@gbtimmon google est un moteur de recherche, il n'est pas analogue à la page de manuel. Il va finalement pointer vers la page de manuel.
Ajay Brahmakshatriya
24

Bien que la question soit étiquetée Unix, les gens peuvent également la visiter lorsque leur plate-forme cible est Windows, et la réponse pour Windows est la GetCurrentDirectory()fonction:

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

Ces réponses s'appliquent à la fois au code C et C ++.

Lien suggéré par l' utilisateur4581301 dans un commentaire à une autre question, et vérifié comme premier choix actuel avec une recherche Google "site: microsoft.com getcurrentdirectory".

Jonathan Leffler
la source
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
la source
3
Pourquoi n'utilisez-vous pas des macros prédéfinies pour détecter un système d'exploitation comme #if defined (_WIN32) || défini (_WIN64) || défini ( WINDOWS )
HaseeB Mir
1

Notez qu'il getcwd(3)est également disponible dans la libc de Microsoft: getcwd (3) et fonctionne de la même manière que vous vous attendez.

Doit être lié à -loldnames(oldnames.lib, ce qui est fait automatiquement dans la plupart des cas), ou utiliser _getcwd(). La version sans préfixe n'est pas disponible sous Windows RT.

rvx
la source
0

Pour obtenir le répertoire actuel (dans lequel vous exécutez votre programme cible), vous pouvez utiliser l'exemple de code suivant, qui fonctionne à la fois pour Visual Studio et Linux / MacOS (gcc / clang), à la fois C et 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
la source